New upstream version 10.48
authorMatthew Vernon <matthew@debian.org>
Mon, 31 Aug 2026 20:36:38 +0000 (21:36 +0100)
committerMatthew Vernon <matthew@debian.org>
Mon, 31 Aug 2026 20:36:38 +0000 (21:36 +0100)
148 files changed:
ChangeLog
MODULE.bazel
Makefile.am
Makefile.in
NEWS
SECURITY.md
SUPPORT-LIFECYCLE.md
build.zig.zon
configure
configure.ac
doc/pcre2-config.1
doc/pcre2-config.txt
doc/pcre2.3
doc/pcre2.txt
doc/pcre2_callout_enumerate.3
doc/pcre2_code_copy.3
doc/pcre2_code_copy_with_tables.3
doc/pcre2_code_free.3
doc/pcre2_compile.3
doc/pcre2_compile_context_copy.3
doc/pcre2_compile_context_create.3
doc/pcre2_compile_context_free.3
doc/pcre2_config.3
doc/pcre2_convert_context_copy.3
doc/pcre2_convert_context_create.3
doc/pcre2_convert_context_free.3
doc/pcre2_converted_pattern_free.3
doc/pcre2_dfa_match.3
doc/pcre2_general_context_copy.3
doc/pcre2_general_context_create.3
doc/pcre2_general_context_free.3
doc/pcre2_get_error_message.3
doc/pcre2_get_mark.3
doc/pcre2_get_match_data_heapframes_size.3
doc/pcre2_get_match_data_size.3
doc/pcre2_get_ovector_count.3
doc/pcre2_get_ovector_pointer.3
doc/pcre2_get_startchar.3
doc/pcre2_jit_compile.3
doc/pcre2_jit_free_unused_memory.3
doc/pcre2_jit_match.3
doc/pcre2_jit_stack_assign.3
doc/pcre2_jit_stack_create.3
doc/pcre2_jit_stack_free.3
doc/pcre2_maketables.3
doc/pcre2_maketables_free.3
doc/pcre2_match.3
doc/pcre2_match_context_copy.3
doc/pcre2_match_context_create.3
doc/pcre2_match_context_free.3
doc/pcre2_match_data_create.3
doc/pcre2_match_data_create_from_pattern.3
doc/pcre2_match_data_free.3
doc/pcre2_next_match.3
doc/pcre2_pattern_convert.3
doc/pcre2_pattern_info.3
doc/pcre2_serialize_decode.3
doc/pcre2_serialize_encode.3
doc/pcre2_serialize_free.3
doc/pcre2_serialize_get_number_of_codes.3
doc/pcre2_set_bsr.3
doc/pcre2_set_callout.3
doc/pcre2_set_character_tables.3
doc/pcre2_set_compile_extra_options.3
doc/pcre2_set_compile_recursion_guard.3
doc/pcre2_set_depth_limit.3
doc/pcre2_set_glob_escape.3
doc/pcre2_set_glob_separator.3
doc/pcre2_set_heap_limit.3
doc/pcre2_set_match_limit.3
doc/pcre2_set_max_pattern_compiled_length.3
doc/pcre2_set_max_pattern_length.3
doc/pcre2_set_max_varlookbehind.3
doc/pcre2_set_newline.3
doc/pcre2_set_offset_limit.3
doc/pcre2_set_optimize.3
doc/pcre2_set_parens_nest_limit.3
doc/pcre2_set_recursion_limit.3
doc/pcre2_set_recursion_memory_management.3
doc/pcre2_set_substitute_callout.3
doc/pcre2_set_substitute_case_callout.3
doc/pcre2_substitute.3
doc/pcre2_substring_copy_byname.3
doc/pcre2_substring_copy_bynumber.3
doc/pcre2_substring_free.3
doc/pcre2_substring_get_byname.3
doc/pcre2_substring_get_bynumber.3
doc/pcre2_substring_length_byname.3
doc/pcre2_substring_length_bynumber.3
doc/pcre2_substring_list_free.3
doc/pcre2_substring_list_get.3
doc/pcre2_substring_nametable_scan.3
doc/pcre2_substring_number_from_name.3
doc/pcre2api.3
doc/pcre2build.3
doc/pcre2callout.3
doc/pcre2compat.3
doc/pcre2convert.3
doc/pcre2demo.3
doc/pcre2grep.1
doc/pcre2grep.txt
doc/pcre2jit.3
doc/pcre2limits.3
doc/pcre2matching.3
doc/pcre2partial.3
doc/pcre2pattern.3
doc/pcre2perform.3
doc/pcre2posix.3
doc/pcre2sample.3
doc/pcre2serialize.3
doc/pcre2syntax.3
doc/pcre2test.1
doc/pcre2test.txt
doc/pcre2unicode.3
patches/pcre2-10.37-Remove-real-POSIX.patch
patches/pcre2-10.40-A-Fixed-a-unicode.patch
patches/pcre2-10.43-Avoid-LIMIT_HEAP-integer.patch
patches/pcre2-10.43-Fix-heapframe-overflow.patch
patches/pcre2-10.44-Fix-incorrect-compiling.patch
patches/pcre2-10.44-Fix-locking-region.patch
patches/pcre2-10.45-Memory-reports-only-compiled.patch
patches/pcre2-10.47-Fix-for-callback.patch
patches/pcre2-10.48-Check-JIT-mode-before-validation.patch [new file with mode: 0644]
patches/pcre2-10.48-Fix-DFA-workspace-overflows.patch [new file with mode: 0644]
patches/pcre2-10.48-Fix-JIT-STR_END.patch [new file with mode: 0644]
patches/pcre2-10.48-Fix-JIT-match-context-reuse.patch [new file with mode: 0644]
patches/pcre2-10.48-Fix-allocation-byte-sizing.patch [new file with mode: 0644]
patches/pcre2-10.48-Fix-character-list-generator.patch [new file with mode: 0644]
patches/pcre2-10.48-Fix-compiler-integer-overflows.patch [new file with mode: 0644]
patches/pcre2-10.48-Fix-invalid-UTF-backwards-scans.patch [new file with mode: 0644]
patches/pcre2-10.48-Fix-repeated-substitute-escapes.patch [new file with mode: 0644]
patches/pcre2-10.48-Fix-scan-prefix-repeat-reset.patch [new file with mode: 0644]
patches/pcre2-10.48-Keep-escape-error-offset-in-pattern.patch [new file with mode: 0644]
patches/pcre2-10.48-Write-serialization-padding.patch [new file with mode: 0644]
src/config.h.generic
src/pcre2.h.generic
src/pcre2_compile.c
src/pcre2_compile_class.c
src/pcre2_dfa_match.c
src/pcre2_extuni.c
src/pcre2_match.c
testdata/testinput10
testdata/testinput12
testdata/testinput6
testdata/testoutput10
testdata/testoutput12-16
testdata/testoutput12-32
testdata/testoutput6

index 8c67c7a07bd0554d8a8219875c015446ae21a98c..01fc8cd6fd9cb12643a45e905a3e51f1a8e84eab 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -8,7 +8,7 @@ Internal changes which are not visible to clients of the library are mostly not
 listed here.
 
 
-Version 10.48 27-August-2026
+Version 10.48 31-August-2026
 ----------------------------
 
 1. (#826) [GHSA-q7rw-r7qq-2hx6] Initialized alignment padding in serialized
@@ -132,11 +132,17 @@ CMAKE_SHARED_LIBRARY_PREFIX_C is customized.
 34. (#961, #962) Fixed two compilation issues preventing use of extended
 (Boolean) character classes before a lookbehind, or inside a lookaround.
 
-35. [GHSA-fmgr-6ggq-9859] Withheld
+35. (GHSA-3r4p-g7gg-ppmf) Fixed an out-of-bounds write in DFA matching when
+using a heap limit; also fixed possible integer overflows which could cause
+under-allocation of the workspace.
 
-36. [GHSA-9qww-pwc4-77qq] Withheld
+36. (GHSA-fmgr-6ggq-9859) Added bounds checks for several integer overflows
+while compiling patterns on 32-bit CPUs, which could cause under-allocation
+followed by out-of-bounds writes.
 
-37. [GHSA-3r4p-g7gg-ppmf] Withheld
+37. (GHSA-9qww-pwc4-77qq) Applied lower buffer bound to prevent two
+out-of-bounds reads while scanning backwards through invalid UTF data with
+PCRE2_MATCH_INVALID_UTF.
 
 
 Version 10.47 21-October-2025
index 70242598cdd3999d79ef83d71d9e62fe30179e8a..ac5e974d9225269901e4c7b1835e32fb46e4750c 100644 (file)
@@ -1,6 +1,6 @@
 module(
     name = "pcre2",
-    version = "10.48-RC1",
+    version = "10.48",
     compatibility_level = 1,
 )
 
index f6f584aa5829a2fb44892817e1e48e511e2d8e66..e112b5c47f5417219a5a5b594fa3a708e6cfb0e8 100644 (file)
@@ -302,7 +302,19 @@ EXTRA_DIST += \
   patches/pcre2-10.44-Fix-incorrect-compiling.patch \
   patches/pcre2-10.44-Fix-locking-region.patch \
   patches/pcre2-10.45-Memory-reports-only-compiled.patch \
-  patches/pcre2-10.47-Fix-for-callback.patch
+  patches/pcre2-10.47-Fix-for-callback.patch \
+  patches/pcre2-10.48-Check-JIT-mode-before-validation.patch \
+  patches/pcre2-10.48-Fix-DFA-workspace-overflows.patch \
+  patches/pcre2-10.48-Fix-JIT-STR_END.patch \
+  patches/pcre2-10.48-Fix-JIT-match-context-reuse.patch \
+  patches/pcre2-10.48-Fix-allocation-byte-sizing.patch \
+  patches/pcre2-10.48-Fix-character-list-generator.patch \
+  patches/pcre2-10.48-Fix-compiler-integer-overflows.patch \
+  patches/pcre2-10.48-Fix-invalid-UTF-backwards-scans.patch \
+  patches/pcre2-10.48-Fix-repeated-substitute-escapes.patch \
+  patches/pcre2-10.48-Fix-scan-prefix-repeat-reset.patch \
+  patches/pcre2-10.48-Keep-escape-error-offset-in-pattern.patch \
+  patches/pcre2-10.48-Write-serialization-padding.patch
 
 # These are support files for building with Bazel or Zig
 
index 2a26fc92cb69b00bc189e8926b446b498d0fa936..756f314276e477c077ba4197875982809ac46c92 100644 (file)
@@ -1373,10 +1373,22 @@ EXTRA_DIST = m4/ax_pthread.m4 m4/pcre2_check_vscript.m4 \
        patches/pcre2-10.44-Fix-incorrect-compiling.patch \
        patches/pcre2-10.44-Fix-locking-region.patch \
        patches/pcre2-10.45-Memory-reports-only-compiled.patch \
-       patches/pcre2-10.47-Fix-for-callback.patch BUILD.bazel \
-       MODULE.bazel build.zig build.zig.zon vms/configure.com \
-       vms/openvms_readme.txt vms/pcre2.h_patch vms/stdint.h \
-       src/pcre2.h.generic src/config.h.generic \
+       patches/pcre2-10.47-Fix-for-callback.patch \
+       patches/pcre2-10.48-Check-JIT-mode-before-validation.patch \
+       patches/pcre2-10.48-Fix-DFA-workspace-overflows.patch \
+       patches/pcre2-10.48-Fix-JIT-STR_END.patch \
+       patches/pcre2-10.48-Fix-JIT-match-context-reuse.patch \
+       patches/pcre2-10.48-Fix-allocation-byte-sizing.patch \
+       patches/pcre2-10.48-Fix-character-list-generator.patch \
+       patches/pcre2-10.48-Fix-compiler-integer-overflows.patch \
+       patches/pcre2-10.48-Fix-invalid-UTF-backwards-scans.patch \
+       patches/pcre2-10.48-Fix-repeated-substitute-escapes.patch \
+       patches/pcre2-10.48-Fix-scan-prefix-repeat-reset.patch \
+       patches/pcre2-10.48-Keep-escape-error-offset-in-pattern.patch \
+       patches/pcre2-10.48-Write-serialization-padding.patch \
+       BUILD.bazel MODULE.bazel build.zig build.zig.zon \
+       vms/configure.com vms/openvms_readme.txt vms/pcre2.h_patch \
+       vms/stdint.h src/pcre2.h.generic src/config.h.generic \
        src/pcre2_chartables.c.dist \
        src/pcre2_chartables.c.ebcdic-1047-nl15 \
        src/pcre2_chartables.c.ebcdic-1047-nl25 deps/sljit/LICENSE \
diff --git a/NEWS b/NEWS
index 94d81b3987d6731ac135ef61c3181e6ebc9ec52c..13cc4c67ff4606a9b7d243a25dc9936cd125c2a0 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,7 +1,7 @@
 News about PCRE2 releases
 -------------------------
 
-Version 10.48 27-August-2026
+Version 10.48 31-August-2026
 ----------------------------
 
 This is a regular release, incorporating security fixes along with small
@@ -10,6 +10,10 @@ improvements and fixes to library behaviour.
 Only changes to behaviour, changes to the API, and other significant changes
 are described here. Please see the ChangeLog and Git log for further details.
 
+As well as the tarball and Git tag for this release, there are detailed
+instructions for backporting security and correctness fixes, for the last
+five years of releases.
+
 * (Git change) Renamed the default development branch from master to main.
 
 * (Maintenance change) Added a five-year support lifecycle policy and
@@ -25,11 +29,17 @@ out-of-bounds read can occur if the match is attempted against invalid UTF input
 is called on untrusted input on platforms with 32-bit size_t, an out-of-bounds
 heap write can occur.
 
-* (Security fix, GHSA-fmgr-6ggq-9859) Withheld
+* (Security fix, GHSA-3r4p-g7gg-ppmf) Fixed an out-of-bounds write in DFA
+matching when using a heap limit; also fixed possible integer overflows which
+could cause under-allocation of the workspace.
 
-* (Security fix, GHSA-9qww-pwc4-77qq) Withheld
+* (Security fix, GHSA-fmgr-6ggq-9859) Added bounds checks for several integer
+overflows while compiling patterns on 32-bit CPUs, which could cause
+under-allocation followed by out-of-bounds writes.
 
-* (Security fix, GHSA-3r4p-g7gg-ppmf) Withheld
+* (Security fix, GHSA-9qww-pwc4-77qq) Applied lower buffer bound to prevent
+two out-of-bounds reads while scanning backwards through invalid UTF data with
+PCRE2_MATCH_INVALID_UTF.
 
 * (Matching correctness) Fixed several matching issues:
   - A JIT-specific matching bug affecting prefix scanning on patterns with
index 4bbe5cd09196816fef55a3ce9259e6ecd71a574e..b5dba4fb1ce9be7b84ff1331cabe876b8a46eaae 100644 (file)
@@ -61,8 +61,17 @@ vulnerability publicly, where advance notification is possible.
 Previous vulnerabilities
 ------------------------
 
-* CVE-2025-58050 (August 2025). Affects 10.45 only (not earlier), and is fixed
-  in 10.46.
+* GHSA-2p8c-ff85-vh9x (July 2026). Affects 10.47 and earlier, and is fixed
+  in 10.48.
+* GHSA-3r4p-g7gg-ppmf (July 2026). Affects 10.32-10.47, and is fixed in 10.48.
+* GHSA-q8g2-wprr-34m9 (May 2026). Affects 10.30-10.47, and is fixed in 10.48.
+* GHSA-9qww-pwc4-77qq (May 2026). Affects 10.34-10.47, and is fixed in 10.48.
+* GHSA-fmgr-6ggq-9859 (January 2026). Affects 10.47 and earlier, and is fixed
+  in 10.48.
+* GHSA-q7rw-r7qq-2hx6 (October 2025). Affects 10.45 and later, and is fixed in
+  10.48.
+* CVE-2025-58050 [GHSA-c2gv-xgf5-5cc2] (August 2025). Affects 10.45 only (not
+  earlier), and is fixed in 10.46.
 * CVE-2022-41409 (July 2023). Only affects test code; no expected impact. Fixed
   in 10.41.
 * CVE-2022-1587 and CVE-2022-1586 (May 2020). Affect versions before 10.40, and
index 7d067b09d2c4cdaafb436e83db98eb1d18d407ac..a4ff17ff9a6a44e3d3a644389ea0ee30995efaaf 100644 (file)
@@ -25,8 +25,24 @@ support status and any new lifecycle recommendations.
 
 * Check this document on each release of PCRE2.
 * Each version of PCRE2 that you are supporting should be listed here.
-* Check for any changes in the "patches to apply" section, and consider
-  backporting these.
+* Check for changes in that version's "backports to apply" section. Apply
+  commits from the release branch according to your distribution's backporting
+  criteria.
+
+The patches are made available in two ways:
+
+* For tarball-based workflows, I am including the dump of the commits
+  containing the changes to be backported. These flat files record the
+  canonical changes, but may require adaptation to an old release.
+
+* For git-based workflows (preferable), I am publishing a release branch for
+  each release - for example, `release/pcre2-10.47`. This branch will always
+  be ahead of the `pcre2-10.47` release tag, and the additional commits
+  consist of the cherry-picked commits, with approved and tested conflict
+  resolutions applied.
+
+  To apply all recommended commits for a release, fetch its branch and
+  merge (or cherry-pick) the commits after the release tag.
 
 ## Support Policy
 
@@ -90,12 +106,34 @@ lifecycle for old (not-latest) PCRE2 releases.
 
 ## Supported Versions
 
-Below is the list of supported PCRE2 versions. For each version, specific
-recommendations and backported fixes (if any) are provided.
+Below is the list of PCRE2 versions supported by upstream distributors. For
+each version, specific recommendations and backported fixes (if any) are
+provided.
+
+### PCRE2 10.23 14-February-2017
+
+* Shipped in RHEL 7 (paid Extended Life Cycle Support ends 31 May 2029).
+
+I am not providing a recommendation of what patches to apply. This release is
+beyond PCRE2's standard five-year support period and is maintained only through
+an extended-support programme.
+
+### PCRE2 10.31 12-February-2018
+
+* Shipped in Ubuntu 18.04 "Bionic Beaver" (Expanded Security Maintenance ends
+  April 2028).
+* Shipped in SUSE Linux Enterprise Server 15 SP1, SP2 and SP3 (paid LTSS
+  Reactive support ends 31 January 2027, 31 December 2027 and 31 December
+  2028, respectively).
+
+I am not providing a recommendation of what patches to apply. These releases
+are beyond PCRE2's standard five-year support period and are maintained only
+through extended-support programmes.
 
 ### PCRE2 10.32 10-September-2018
 
-* Shipped in RHEL/CentOS 8 (EOL 31 May 2024).
+* Shipped in RHEL 8 (Maintenance Support ends 31 May 2029; paid Extended Life
+  Cycle support ends 31 May 2033).
 
 This version is older than 5 years, but remains listed in SUPPORT-LIFECYCLE.md
 potentially until May 2029 (end of "Maintenance Support" for RHEL 8), in
@@ -111,6 +149,17 @@ https://gitlab.com/redhat/centos-stream/rpms/pcre2/-/tree/c8s?ref_type=heads
 The most serious of these was the backported mitigation for CVE-2019-20454 from
 the fix in 10.34.
 
+### PCRE2 10.34 21-November-2019
+
+* Shipped in Ubuntu 20.04 "Focal Fossa" (Expanded Security Maintenance ends
+  April 2030).
+* Shipped in SUSE Linux Enterprise Server 12 SP5 (paid LTSS ends 31 October
+  2027).
+
+I am not providing a recommendation of what patches to apply. These releases
+are beyond PCRE2's standard five-year support period and are maintained only
+through extended-support programmes.
+
 ### PCRE2 10.36 04-December-2020
 
 * Shipped in Debian 11 "Bullseye" (EOL 31 Aug 2026).
@@ -140,10 +189,18 @@ Do not use (update to 10.39).
 ### PCRE2 10.39 29-October-2021
 
 * Shipped in Ubuntu 22.04 "Jammy Jellyfish" (EOL 01 Apr 2027).
-
-I am not providing a recommendation of what patches to apply. Distributors still
-shipping this release have likely frozen their codebase at this point, since the
-release of Ubuntu 24.04.
+* Shipped in SUSE Linux Enterprise Server 15 SP4 and SP5 (paid LTSS ends 31
+  December 2026 and 31 December 2027, respectively).
+
+Backports to apply:
+* `patches/pcre2-10.40-A-Fixed-a-unicode.patch`
+* `patches/pcre2-10.40-B-Fixed-an-issue-affecting.patch`
+* `patches/pcre2-10.48-Fix-JIT-match-context-reuse.patch`
+* `patches/pcre2-10.48-Check-JIT-mode-before-validation.patch`
+* `patches/pcre2-10.48-Fix-allocation-byte-sizing.patch`
+* `patches/pcre2-10.48-Fix-invalid-UTF-backwards-scans.patch`
+* `patches/pcre2-10.48-Fix-compiler-integer-overflows.patch`
+* `patches/pcre2-10.48-Fix-DFA-workspace-overflows.patch`
 
 Patches introduced:
 * `patches/pcre2-10.39-Fix-incorrect-detection.patch`: Significant bugfix for
@@ -151,11 +208,17 @@ Patches introduced:
 
 ### PCRE2 10.40 15-April-2022
 
-* Shipped in RHEL/CentOS 9 (EOL 31 May 2027).
+* Shipped in RHEL 9 (Full Support ends 31 May 2027; Maintenance Support ends 31
+  May 2032; paid Extended Life Cycle support ends 31 May 2036).
+* Shipped in CentOS Stream 9 (EOL 31 May 2027).
 
-I am not providing a recommendation of what patches to apply. Distributors still
-shipping this release have likely frozen their codebase at this point, since the
-release of RHEL 10.
+Backports to apply:
+* `patches/pcre2-10.48-Fix-JIT-match-context-reuse.patch`
+* `patches/pcre2-10.48-Check-JIT-mode-before-validation.patch`
+* `patches/pcre2-10.48-Fix-allocation-byte-sizing.patch`
+* `patches/pcre2-10.48-Fix-invalid-UTF-backwards-scans.patch`
+* `patches/pcre2-10.48-Fix-compiler-integer-overflows.patch`
+* `patches/pcre2-10.48-Fix-DFA-workspace-overflows.patch`
 
 For the record, RHEL/CentOS 9 ships rather more backported patches than other
 distributions:
@@ -166,9 +229,11 @@ tested them myself for compatibility with 10.40 or other earlier releases.
 
 Patches introduced:
 * `patches/pcre2-10.40-A-Fixed-a-unicode.patch`: Fixed CVE-2022-1586. This
-  affects all recent previous versions of PCRE2.
+  should be assumed to affect all previous versions of PCRE2 (lower bound of
+  affected releases unconfirmed).
 * `patches/pcre2-10.40-B-Fixed-an-issue-affecting.patch`: Fixed CVE-2022-1587.
-  This affects all recent previous versions of PCRE2.
+  This should be assumed to affect all previous versions of PCRE2 (lower bound
+  of affected releases unconfirmed).
 
 ### PCRE2 10.41 06-December-2022
 
@@ -180,25 +245,39 @@ for the test suite, so this fix is not backported.
 ### PCRE2 10.42 11-December-2022
 
 * Shipped in Debian 12 "Bookworm" (EOL 30 Jun 2028).
-* Shipped in Ubuntu 24.04 "Noble Numbat" (EOL 25 Apr 2029).
+* Shipped in Ubuntu 24.04 "Noble Numbat" (EOL 31 May 2029).
+* Shipped in SUSE Linux Enterprise Server 15 SP6 and SP7 (paid LTSS ends 31
+  December 2028 and general support ends 31 July 2031, respectively).
 
 Users on RISC-V are advised to update to 10.43, or not use the JIT unless using
 a backport for https://github.com/zherczeg/sljit/pull/223. Given the small
 RISC-V userbase (especially on older releases), disabling the JIT for RISC-V
 builds is likely acceptable.
 
-Patches to apply:
+Backports to apply:
 * `patches/pcre2-10.43-Avoid-LIMIT_HEAP-integer.patch`
 * `patches/pcre2-10.43-Fix-heapframe-overflow.patch`
+* `patches/pcre2-10.48-Fix-JIT-match-context-reuse.patch`
+* `patches/pcre2-10.48-Check-JIT-mode-before-validation.patch`
+* `patches/pcre2-10.48-Fix-allocation-byte-sizing.patch`
+* `patches/pcre2-10.48-Fix-invalid-UTF-backwards-scans.patch`
+* `patches/pcre2-10.48-Fix-compiler-integer-overflows.patch`
+* `patches/pcre2-10.48-Fix-DFA-workspace-overflows.patch`
 
 ### PCRE2 10.43 16-February-2024
 
-* Shipped in Alpine 3.20 (EOL 01 Apr 2026)
-* Shipped in Alpine 3.21 (EOL 01 Nov 2026)
+* Shipped in Alpine 3.21 (EOL 01 Nov 2026).
 
-Patches to apply:
+Backports to apply:
 * `patches/pcre2-10.44-Fix-locking-region.patch`
 * `patches/pcre2-10.44-Fix-incorrect-compiling.patch`
+* `patches/pcre2-10.48-Fix-JIT-STR_END.patch`
+* `patches/pcre2-10.48-Fix-JIT-match-context-reuse.patch`
+* `patches/pcre2-10.48-Check-JIT-mode-before-validation.patch`
+* `patches/pcre2-10.48-Fix-allocation-byte-sizing.patch`
+* `patches/pcre2-10.48-Fix-invalid-UTF-backwards-scans.patch`
+* `patches/pcre2-10.48-Fix-compiler-integer-overflows.patch`
+* `patches/pcre2-10.48-Fix-DFA-workspace-overflows.patch`
 
 Patches introduced:
 * `patches/pcre2-10.43-Avoid-LIMIT_HEAP-integer.patch`: Fix integer overflow in
@@ -207,15 +286,24 @@ Patches introduced:
   heap-allocated frames vector. This patch is therefore recommended for
   backporting to 10.42 only.
 * `patches/pcre2-10.43-Fix-heapframe-overflow.patch`: Fix buffer overrun in
-  handling of LIMIT_HEAP. These patches can be backported to all recent previous
-  versions (since LIMIT_HEAP was introduced in 10.30).
+  handling of LIMIT_HEAP. The regression was introduced in d90fb238 in PCRE2
+  10.41, so the patch is for backporting to 10.41-42.
 
 ### PCRE2 10.44 07-June-2024
 
-* Shipped in RHEL/CentOS 10 (EOL 31 May 2030).
+* Shipped in RHEL 10 (Full Support ends 31 May 2030; Maintenance Support ends
+  31 May 2035; paid Extended Life Cycle support ends 31 May 2039).
+* Shipped in CentOS Stream 10 (EOL 31 May 2030).
 
-Patches to apply:
+Backports to apply:
 * `patches/pcre2-10.45-Memory-reports-only-compiled.patch`
+* `patches/pcre2-10.48-Fix-JIT-STR_END.patch`
+* `patches/pcre2-10.48-Fix-JIT-match-context-reuse.patch`
+* `patches/pcre2-10.48-Check-JIT-mode-before-validation.patch`
+* `patches/pcre2-10.48-Fix-allocation-byte-sizing.patch`
+* `patches/pcre2-10.48-Fix-invalid-UTF-backwards-scans.patch`
+* `patches/pcre2-10.48-Fix-compiler-integer-overflows.patch`
+* `patches/pcre2-10.48-Fix-DFA-workspace-overflows.patch`
 
 Patches introduced:
 * `patches/pcre2-10.44-Fix-locking-region.patch`: To be backported to 10.43 only
@@ -228,6 +316,10 @@ Patches introduced:
 
 ### PCRE2 10.45 05-February-2025
 
+* Shipped in openSUSE Leap 16.0 (EOL 31 October 2027).
+* Shipped in SUSE Linux Enterprise Server 16.0 (general support ends 30
+  November 2027).
+
 Do not use (update to 10.46, which is is a drop-in compatible release with a
 security fix).
 
@@ -239,16 +331,47 @@ Patches introduced:
 ### PCRE2 10.46 27-August-2025
 
 * Shipped in Debian 13 "Trixie" (EOL 30 Jun 2030).
-* Shipped in Alpine 3.22 (EOL 01 May 2027)
+* Shipped in Ubuntu 26.04 "Resolute Raccoon" (EOL 30 April 2031).
+* Shipped in Alpine 3.22 (EOL 01 May 2027).
+* Shipped in NixOS 26.05 (EOL 31 December 2026).
 
 Introduced the fix for CVE-2025-58050. This only affects 10.45. Do not backport
 the patch (just update to 10.46).
 
-Patches to apply:
+Backports to apply:
 * `patches/pcre2-10.47-Fix-for-callback.patch`
+* `patches/pcre2-10.48-Write-serialization-padding.patch`
+* `patches/pcre2-10.48-Fix-character-list-generator.patch`
+* `patches/pcre2-10.48-Fix-scan-prefix-repeat-reset.patch`
+* `patches/pcre2-10.48-Fix-JIT-STR_END.patch`
+* `patches/pcre2-10.48-Fix-JIT-match-context-reuse.patch`
+* `patches/pcre2-10.48-Check-JIT-mode-before-validation.patch`
+* `patches/pcre2-10.48-Fix-allocation-byte-sizing.patch`
+* `patches/pcre2-10.48-Fix-invalid-UTF-backwards-scans.patch`
+* `patches/pcre2-10.48-Fix-compiler-integer-overflows.patch`
+* `patches/pcre2-10.48-Fix-DFA-workspace-overflows.patch`
 
 ### PCRE2 10.47 21-October-2025
 
+* Shipped in Fedora 43 (EOL 09 December 2026) and Fedora 44 (EOL 02 June
+  2027).
+* Shipped in Alpine 3.23 (EOL 01 November 2027) and Alpine 3.24 (EOL 01 June
+  2028).
+
+Backports to apply:
+* `patches/pcre2-10.48-Write-serialization-padding.patch`
+* `patches/pcre2-10.48-Fix-character-list-generator.patch`
+* `patches/pcre2-10.48-Fix-repeated-substitute-escapes.patch`
+* `patches/pcre2-10.48-Fix-scan-prefix-repeat-reset.patch`
+* `patches/pcre2-10.48-Fix-JIT-STR_END.patch`
+* `patches/pcre2-10.48-Fix-JIT-match-context-reuse.patch`
+* `patches/pcre2-10.48-Check-JIT-mode-before-validation.patch`
+* `patches/pcre2-10.48-Fix-allocation-byte-sizing.patch`
+* `patches/pcre2-10.48-Keep-escape-error-offset-in-pattern.patch`
+* `patches/pcre2-10.48-Fix-invalid-UTF-backwards-scans.patch`
+* `patches/pcre2-10.48-Fix-compiler-integer-overflows.patch`
+* `patches/pcre2-10.48-Fix-DFA-workspace-overflows.patch`
+
 Patches introduced:
 * `patches/pcre2-10.47-Fix-for-callback.patch`: A fix for a significant memory
   read overrun in a function rarely called by applications, to be backported to
@@ -257,6 +380,53 @@ Patches introduced:
   fixing crashes and out-of-bounds memory reads in the previous, legacy AArch64
   JIT. This is probably not possible to backport.
 
-### PCRE2 10.48 27-August-2026
+### PCRE2 10.48 31-August-2026
 
-**To be confirmed.**
+Patches introduced:
+* `patches/pcre2-10.48-Write-serialization-padding.patch`: Initializes
+  character-list padding before serialization, preventing a two-byte
+  information disclosure (GHSA-q7rw-r7qq-2hx6). The affected representation
+  was introduced in 10.45; affected releases are 10.45-10.47.
+* `patches/pcre2-10.48-Fix-character-list-generator.patch`: Fixes incorrect
+  compilation and false-negative matches for Unicode character lists around
+  U+0100 and ranges crossing U+00FF. The affected representation was
+  introduced in 10.45; affected releases are 10.45-10.47.
+* `patches/pcre2-10.48-Fix-repeated-substitute-escapes.patch`: Fixes incorrect
+  conditional substitution output and errors after consecutive extended
+  replacement escapes. This regression was introduced in 10.47 and affects
+  10.47 only.
+* `patches/pcre2-10.48-Fix-scan-prefix-repeat-reset.patch`: Fixes JIT false
+  negatives caused by stale repeat state during prefix scanning. The affected
+  scan-prefix implementation was introduced in 10.45; affected releases are
+  10.45-10.47.
+* `patches/pcre2-10.48-Fix-JIT-STR_END.patch`: Restores `STR_END` while JIT
+  backtracks through non-atomic variable-length lookbehinds. The affected JIT
+  support was introduced in 10.43; affected releases are 10.43-10.47.
+* `patches/pcre2-10.48-Fix-JIT-match-context-reuse.patch`: Prevents direct
+  `pcre2_jit_match()` reuse from leaking a copied subject, retaining stale
+  ownership state, or freeing caller-owned memory. Copied-subject support was
+  introduced in 10.33; affected releases are 10.33-10.47.
+* `patches/pcre2-10.48-Check-JIT-mode-before-validation.patch`: Checks that the
+  requested JIT mode exists before JIT validation and execution
+  (GHSA-2p8c-ff85-vh9x). The accompanying regression test is part of the same
+  backport series. The affected invalid-UTF fallback was introduced in 10.34;
+  affected releases are 10.34-10.47.
+* `patches/pcre2-10.48-Fix-allocation-byte-sizing.patch`: Uses byte sizes for
+  two allocations and adds overflow checks (GHSA-q8g2-wprr-34m9). One affected
+  allocation has been confirmed as far back as PCRE2 10.00; affected releases
+  are 10.47 and earlier.
+* `patches/pcre2-10.48-Keep-escape-error-offset-in-pattern.patch`: Keeps error
+  offsets within malformed patterns ending in incomplete `\x{`, `\o{`, or
+  `\N{U+` escapes. This regression was introduced in 10.47 and affects 10.47
+  only.
+* `patches/pcre2-10.48-Fix-invalid-UTF-backwards-scans.patch`: Prevents two
+  out-of-bounds reads while scanning backwards through invalid UTF data
+  (GHSA-9qww-pwc4-77qq). Invalid-UTF matching was introduced in 10.34; affected
+  releases are 10.34-10.47.
+* `patches/pcre2-10.48-Fix-compiler-integer-overflows.patch`: Adds bounds checks
+  for several integer overflows while compiling patterns
+  (GHSA-fmgr-6ggq-9859). The affected generic calculations have been confirmed
+  in PCRE2 10.00; affected releases are 10.47 and earlier.
+* `patches/pcre2-10.48-Fix-DFA-workspace-overflows.patch`: Prevents workspace
+  size and offset overflows in DFA matching (GHSA-3r4p-g7gg-ppmf). The affected
+  heap workspace was introduced in 10.32; affected releases are 10.32-10.47.
index a97741567d37599b38d4249daffb77fe30fba997..eda90114281c615e694b4815a6c0a9ed5759d5b2 100644 (file)
@@ -1,6 +1,6 @@
 .{
     .name = .pcre2,
-    .version = "10.48.0-RC1",
+    .version = "10.48.0",
 
     // Do NOT change this for new releases.
     // DO change this if making a fork of PCRE2 which is used by any Zig clients.
index de94aeb4adc1fc53520ab0ec8fcb39bb8830c5ec..f0deee07f2c86c1af50069638f77f96faa32d273 100755 (executable)
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.71 for PCRE2 10.48-RC1.
+# Generated by GNU Autoconf 2.71 for PCRE2 10.48.
 #
 #
 # Copyright (C) 1992-1996, 1998-2017, 2020-2021 Free Software Foundation,
@@ -626,8 +626,8 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='PCRE2'
 PACKAGE_TARNAME='pcre2'
-PACKAGE_VERSION='10.48-RC1'
-PACKAGE_STRING='PCRE2 10.48-RC1'
+PACKAGE_VERSION='10.48'
+PACKAGE_STRING='PCRE2 10.48'
 PACKAGE_BUGREPORT=''
 PACKAGE_URL=''
 
@@ -1480,7 +1480,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures PCRE2 10.48-RC1 to adapt to many kinds of systems.
+\`configure' configures PCRE2 10.48 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1551,7 +1551,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of PCRE2 10.48-RC1:";;
+     short | recursive ) echo "Configuration of PCRE2 10.48:";;
    esac
   cat <<\_ACEOF
 
@@ -1748,7 +1748,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-PCRE2 configure 10.48-RC1
+PCRE2 configure 10.48
 generated by GNU Autoconf 2.71
 
 Copyright (C) 2021 Free Software Foundation, Inc.
@@ -2141,7 +2141,7 @@ cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by PCRE2 $as_me 10.48-RC1, which was
+It was created by PCRE2 $as_me 10.48, which was
 generated by GNU Autoconf 2.71.  Invocation command line was
 
   $ $0$ac_configure_args_raw
@@ -3413,7 +3413,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='pcre2'
- VERSION='10.48-RC1'
+ VERSION='10.48'
 
 
 printf "%s\n" "#define PACKAGE \"$PACKAGE\"" >>confdefs.h
@@ -14229,7 +14229,7 @@ Usage: $0 [OPTIONS]
 Report bugs to <bug-libtool@gnu.org>."
 
 lt_cl_version="\
-PCRE2 config.lt 10.48-RC1
+PCRE2 config.lt 10.48
 configured by $0, generated by GNU Autoconf 2.71.
 
 Copyright (C) 2011 Free Software Foundation, Inc.
@@ -15849,8 +15849,8 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
 PCRE2_MAJOR="10"
 PCRE2_MINOR="48"
-PCRE2_PRERELEASE="-RC1"
-PCRE2_DATE="2026-08-27"
+PCRE2_PRERELEASE=""
+PCRE2_DATE="2026-08-31"
 
 if test "$PCRE2_MINOR" = "08" -o "$PCRE2_MINOR" = "09"
 then
@@ -19548,7 +19548,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by PCRE2 $as_me 10.48-RC1, which was
+This file was extended by PCRE2 $as_me 10.48, which was
 generated by GNU Autoconf 2.71.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -19616,7 +19616,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config='$ac_cs_config_escaped'
 ac_cs_version="\\
-PCRE2 config.status 10.48-RC1
+PCRE2 config.status 10.48
 configured by $0, generated by GNU Autoconf 2.71,
   with options \\"\$ac_cs_config\\"
 
index 8592c2ea56eaf9272a103bd98f0b2c424784ba32..62b13082e2a50f9f8163e284e41cb189d68563dc 100644 (file)
@@ -10,8 +10,8 @@ dnl be defined as -RC2, for example. For real releases, it should be empty.
 
 m4_define(pcre2_major, [10])
 m4_define(pcre2_minor, [48])
-m4_define(pcre2_prerelease, [-RC1])
-m4_define(pcre2_date, [2026-08-27])
+m4_define(pcre2_prerelease, [])
+m4_define(pcre2_date, [2026-08-31])
 
 # Libtool shared library interface versions (current:revision:age)
 m4_define(libpcre2_8_version,     [16:0:16])
index e72663fa357fdccd449fd7514ea4e976642f1496..4c99a15f76c03a3ac01871c1a9eb692bf6b28d77 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2-CONFIG 1 "22 February 2025" "PCRE2 10.48-RC1"
+.TH PCRE2-CONFIG 1 "22 February 2025" "PCRE2 10.48"
 .SH NAME
 pcre2-config - program to return PCRE2 configuration
 .SH SYNOPSIS
index c134a6ab0404b62cd1740ca9f124c26a669c54b3..b1a707002947f7326ddde9d7c564153b106a5f39 100644 (file)
@@ -81,4 +81,4 @@ REVISION
        Last updated: 22 February 2025
 
 
-PCRE2 10.48-RC1                22 February 2025                PCRE2-CONFIG(1)
+PCRE2 10.48                    22 February 2025                PCRE2-CONFIG(1)
index 0698b67fa0303d7241d76b39c257bff4abef6006..ce4b04cd4f4e987dfdbef87d7215d6169375d3e3 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2 3 "22 February 2025" "PCRE2 10.48-RC1"
+.TH PCRE2 3 "22 February 2025" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH INTRODUCTION
index f934cd20970589f2030a61ed54a863a4ccc3036e..dc2cee1a74d2660e2a12b07462fbc4401dda1b26 100644 (file)
@@ -189,7 +189,7 @@ REVISION
        Copyright (c) 1997-2021 University of Cambridge.
 
 
-PCRE2 10.48-RC1                22 February 2025                       PCRE2(3)
+PCRE2 10.48                    22 February 2025                       PCRE2(3)
 ------------------------------------------------------------------------------
 
 
@@ -4440,7 +4440,7 @@ REVISION
        Copyright (c) 1997-2024 University of Cambridge.
 
 
-PCRE2 10.48-RC1                08 December 2025                    PCRE2API(3)
+PCRE2 10.48                    08 December 2025                    PCRE2API(3)
 ------------------------------------------------------------------------------
 
 
@@ -5087,7 +5087,7 @@ REVISION
        Copyright (c) 1997-2024 University of Cambridge.
 
 
-PCRE2 10.48-RC1                 17 October 2025                  PCRE2BUILD(3)
+PCRE2 10.48                     17 October 2025                  PCRE2BUILD(3)
 ------------------------------------------------------------------------------
 
 
@@ -5520,7 +5520,7 @@ REVISION
        Copyright (c) 1997-2024 University of Cambridge.
 
 
-PCRE2 10.48-RC1                26 February 2025                PCRE2CALLOUT(3)
+PCRE2 10.48                    26 February 2025                PCRE2CALLOUT(3)
 ------------------------------------------------------------------------------
 
 
@@ -5779,7 +5779,7 @@ REVISION
        Copyright (c) 1997-2024 University of Cambridge.
 
 
-PCRE2 10.48-RC1                  02 June 2025                   PCRE2COMPAT(3)
+PCRE2 10.48                      02 June 2025                   PCRE2COMPAT(3)
 ------------------------------------------------------------------------------
 
 
@@ -6234,7 +6234,7 @@ REVISION
        Copyright (c) 1997-2024 University of Cambridge.
 
 
-PCRE2 10.48-RC1                 08 August 2026                     PCRE2JIT(3)
+PCRE2 10.48                     08 August 2026                     PCRE2JIT(3)
 ------------------------------------------------------------------------------
 
 
@@ -6319,7 +6319,7 @@ REVISION
        Copyright (c) 1997-2023 University of Cambridge.
 
 
-PCRE2 10.48-RC1                03 September 2025                PCRE2LIMITS(3)
+PCRE2 10.48                    03 September 2025                PCRE2LIMITS(3)
 ------------------------------------------------------------------------------
 
 
@@ -6552,7 +6552,7 @@ REVISION
        Copyright (c) 1997-2024 University of Cambridge.
 
 
-PCRE2 10.48-RC1                22 February 2025               PCRE2MATCHING(3)
+PCRE2 10.48                    22 February 2025               PCRE2MATCHING(3)
 ------------------------------------------------------------------------------
 
 
@@ -6949,7 +6949,7 @@ REVISION
        Copyright (c) 1997-2019 University of Cambridge.
 
 
-PCRE2 10.48-RC1                 16 August 2026                 PCRE2PARTIAL(3)
+PCRE2 10.48                     16 August 2026                 PCRE2PARTIAL(3)
 ------------------------------------------------------------------------------
 
 
@@ -10818,7 +10818,7 @@ REVISION
        Copyright (c) 1997-2024 University of Cambridge.
 
 
-PCRE2 10.48-RC1                 25 October 2025                PCRE2PATTERN(3)
+PCRE2 10.48                     25 October 2025                PCRE2PATTERN(3)
 ------------------------------------------------------------------------------
 
 
@@ -11073,7 +11073,7 @@ REVISION
        Copyright (c) 1997-2022 University of Cambridge.
 
 
-PCRE2 10.48-RC1                06 December 2022                PCRE2PERFORM(3)
+PCRE2 10.48                    06 December 2022                PCRE2PERFORM(3)
 ------------------------------------------------------------------------------
 
 
@@ -11431,7 +11431,7 @@ REVISION
        Copyright (c) 1997-2024 University of Cambridge.
 
 
-PCRE2 10.48-RC1                27 November 2024                  PCRE2POSIX(3)
+PCRE2 10.48                    27 November 2024                  PCRE2POSIX(3)
 ------------------------------------------------------------------------------
 
 
@@ -11525,7 +11525,7 @@ REVISION
        Copyright (c) 1997-2016 University of Cambridge.
 
 
-PCRE2 10.48-RC1                28 February 2025                 PCRE2SAMPLE(3)
+PCRE2 10.48                    28 February 2025                 PCRE2SAMPLE(3)
 ------------------------------------------------------------------------------
 PCRE2SERIALIZE(3)          Library Functions Manual          PCRE2SERIALIZE(3)
 
@@ -11716,7 +11716,7 @@ REVISION
        Copyright (c) 1997-2018 University of Cambridge.
 
 
-PCRE2 10.48-RC1                 19 January 2024              PCRE2SERIALIZE(3)
+PCRE2 10.48                     19 January 2024              PCRE2SERIALIZE(3)
 ------------------------------------------------------------------------------
 
 
@@ -12448,7 +12448,7 @@ REVISION
        Copyright (c) 1997-2024 University of Cambridge.
 
 
-PCRE2 10.48-RC1                 14 October 2025                 PCRE2SYNTAX(3)
+PCRE2 10.48                     14 October 2025                 PCRE2SYNTAX(3)
 ------------------------------------------------------------------------------
 
 
@@ -12943,7 +12943,7 @@ REVISION
        Copyright (c) 1997-2024 University of Cambridge.
 
 
-PCRE2 10.48-RC1                27 November 2024                PCRE2UNICODE(3)
+PCRE2 10.48                    27 November 2024                PCRE2UNICODE(3)
 ------------------------------------------------------------------------------
 
 
index 32bfa33669870ac490259de7a34e27a3a92c497c..53b64ae09f1fe8ab5a3349c27b48a218d09e422a 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2_COMPILE 3 "23 March 2017" "PCRE2 10.48-RC1"
+.TH PCRE2_COMPILE 3 "23 March 2017" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
index c5038abaa95b82629bbbe76817e8a11e47c04958..9fa48c0474aecbf5c1b91e6bc7ef6a5a92795090 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2_CODE_COPY 3 "22 November 2016" "PCRE2 10.48-RC1"
+.TH PCRE2_CODE_COPY 3 "22 November 2016" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
index 4252e6dfcfacc2da88a31cd079ba2aef092decab..77bb7f7cefcad01bc95a3935da82d74efce0ba3e 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2_CODE_COPY 3 "16 January 2017" "PCRE2 10.48-RC1"
+.TH PCRE2_CODE_COPY 3 "16 January 2017" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
index a538b1e75579551ed1d22d43e00ca77dd7aefda1..cfd1f621b0f3b5b60495f5beebd4b57f6c943bc4 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2_CODE_FREE 3 "28 June 2018" "PCRE2 10.48-RC1"
+.TH PCRE2_CODE_FREE 3 "28 June 2018" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
index ec3bb9a87d47b5657213d751150b651c281167ee..4c0eccd987604f4c81607328d103f3ed9e299f41 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2_COMPILE 3 "30 October 2024" "PCRE2 10.48-RC1"
+.TH PCRE2_COMPILE 3 "30 October 2024" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
index 15a85fbd57b616e23d0f585fca6acb308ea25a74..b8ec3d730049583d2796f0240dd349e174e6baa0 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2_COMPILE_CONTEXT_COPY 3 "25 October 2014" "PCRE2 10.48-RC1"
+.TH PCRE2_COMPILE_CONTEXT_COPY 3 "25 October 2014" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
index 87f7b52343715eea07700977fd84d25a7e7400ee..3522a0541f400b3bbd63315191b1562c01af7d07 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2_COMPILE_CONTEXT_CREATE 3 "25 October 2014" "PCRE2 10.48-RC1"
+.TH PCRE2_COMPILE_CONTEXT_CREATE 3 "25 October 2014" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
index d51fc9d85a389428b0055e180cc26d36c077363a..75d358504daa4aa34674e4a4891349f2564f5300 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2_COMPILE_CONTEXT_FREE 3 "28 June 2018" "PCRE2 10.48-RC1"
+.TH PCRE2_COMPILE_CONTEXT_FREE 3 "28 June 2018" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
index 785bd00511533b5e981439b874c8123cda671a1b..24142971614405138ca0fe807d1e0a333c8180ea 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2_CONFIG 3 "03 September 2025" "PCRE2 10.48-RC1"
+.TH PCRE2_CONFIG 3 "03 September 2025" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
index 2c9e78bd62c24123216466396519be6c58c091f3..0c5178a657e229acf9f25b154252b4d14b1ebe34 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2_CONVERT_CONTEXT_COPY 3 "12 July 2017" "PCRE2 10.48-RC1"
+.TH PCRE2_CONVERT_CONTEXT_COPY 3 "12 July 2017" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
index 7a5589439484fd5c95bb708c0adcd92e94171ee3..16d42eeee3916a17b279bcb0ae20885d19429f8a 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2_CONVERT_CONTEXT_CREATE 3 "12 July 2017" "PCRE2 10.48-RC1"
+.TH PCRE2_CONVERT_CONTEXT_CREATE 3 "12 July 2017" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
index 874982b3b59f0f656c414de72976534b2647694e..5918645914af703563222b55e976d90c9e7dea74 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2_CONVERT_CONTEXT_FREE 3 "13 August 2018" "PCRE2 10.48-RC1"
+.TH PCRE2_CONVERT_CONTEXT_FREE 3 "13 August 2018" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
index b195236661c0c2c7d88c6493cccad664a84c9399..d955f79d37c7f7329edf2fb0879703c0e5d36691 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2_CONVERTED_PATTERN_FREE 3 "13 August 2018" "PCRE2 10.48-RC1"
+.TH PCRE2_CONVERTED_PATTERN_FREE 3 "13 August 2018" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
index f6ee61372647118ebc7a6e12c3ea309a73937ffb..e5de75f24625359c85b089ba9c79f56ad040f713 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2_DFA_MATCH 3 "31 August 2021" "PCRE2 10.48-RC1"
+.TH PCRE2_DFA_MATCH 3 "31 August 2021" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
index 0de6743965ff4a0522ed66b492701278a0b1a615..3993cd240efd86a2b221bc7d184cc8be8bde6c88 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2_GENERAL_CONTEXT_COPY 3 "25 October 2014" "PCRE2 10.48-RC1"
+.TH PCRE2_GENERAL_CONTEXT_COPY 3 "25 October 2014" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
index d35dfa2606d89b3d6e60a5d27fa5bd43eb9d2636..cc85e45206ad33a4956fe1bab28562a7490011a5 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2_GENERAL_CONTEXT_CREATE 3 "23 January 2023" "PCRE2 10.48-RC1"
+.TH PCRE2_GENERAL_CONTEXT_CREATE 3 "23 January 2023" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
index b056780a5e4e4fb482a3587a50e0e27a2f43ee0b..8069c65acc6e215f934e989e114508fb73244ee6 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2_GENERAL_CONTEXT_FREE 3 "28 June 2018" "PCRE2 10.48-RC1"
+.TH PCRE2_GENERAL_CONTEXT_FREE 3 "28 June 2018" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
index d7b66577e78cd53759a8c059575c7491fccebdb6..7d8734140d2b716a9b882df12f44e8aeee460ae1 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2_GET_ERROR_MESSAGE 3 "24 March 2017" "PCRE2 10.48-RC1"
+.TH PCRE2_GET_ERROR_MESSAGE 3 "24 March 2017" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
index 4ead97a5f66eccd5a5d49892f55bb44fa1bae13a..4e870ae668c21a991557b00d65c9a315a4175948 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2_GET_MARK 3 "13 January 2018" "PCRE2 10.48-RC1"
+.TH PCRE2_GET_MARK 3 "13 January 2018" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
index b10e663c4470f47d5267e4d76d5177e888f27697..33f016e981eb4d7113097d83350ab9b3603d9b4a 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2_GET_MATCH_DATA_HEAPFRAMES_SIZE 3 "18 January 2023" "PCRE2 10.48-RC1"
+.TH PCRE2_GET_MATCH_DATA_HEAPFRAMES_SIZE 3 "18 January 2023" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
index e7940b55bc1de6057e371076ce5b5a6ac55cf685..5216e99095ae33362898aab91403ecf2a8fa5b31 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2_GET_MATCH_DATA_SIZE 3 "17 October 2019" "PCRE2 10.48-RC1"
+.TH PCRE2_GET_MATCH_DATA_SIZE 3 "17 October 2019" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
index b6ef0e6dc67965d62f1a29e76fdd8cc1011484eb..803d39eaf12c6a18f66f00a61a35e6bad096a1e7 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2_GET_OVECTOR_COUNT 3 "25 October 2014" "PCRE2 10.48-RC1"
+.TH PCRE2_GET_OVECTOR_COUNT 3 "25 October 2014" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
index 5a0d16862478ba3d023b279a7719724b7939ebb0..bc42d3d3839731e1ea9fa2a5f88e3e99ea7e3b57 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2_GET_OVECTOR_POINTER 3 "25 October 2014" "PCRE2 10.48-RC1"
+.TH PCRE2_GET_OVECTOR_POINTER 3 "25 October 2014" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
index bd1bf168618bb7440cb986beae4d2651fd05ec82..40a8ba61760de31f4da146ebc7907efb7dcc15d7 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2_GET_STARTCHAR 3 "25 October 2014" "PCRE2 10.48-RC1"
+.TH PCRE2_GET_STARTCHAR 3 "25 October 2014" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
index 410e2d21970839377087ebbdd0a6ff901c9d3576..bc95717215b78f06a55d77c491d1582659cab4e5 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2_JIT_COMPILE 3 "22 August 2024" "PCRE2 10.48-RC1"
+.TH PCRE2_JIT_COMPILE 3 "22 August 2024" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
index ec7ea363686024901945589808eff3dd4ac1e4cd..c0318da01798e6c1dc980aed3f526edd94b33cc6 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2_JIT_FREE_UNUSED_MEMORY 3 "24 April 2020" "PCRE2 10.48-RC1"
+.TH PCRE2_JIT_FREE_UNUSED_MEMORY 3 "24 April 2020" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
index e82c129e2fc678ee970d4c2b8073c150963c6e79..5cc914ba9c24b8a614e0ec46b9b57ea722721fc0 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2_JIT_MATCH 3 "20 January 2023" "PCRE2 10.48-RC1"
+.TH PCRE2_JIT_MATCH 3 "20 January 2023" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
index 763c8b5bf932e20dfbd0fa35698280337b6b992d..76056325b5b5a79a722e6623aa1373e3d2bad8f2 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2_JIT_STACK_ASSIGN 3 "13 August 2018" "PCRE2 10.48-RC1"
+.TH PCRE2_JIT_STACK_ASSIGN 3 "13 August 2018" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
index 055bb9d605462db2968dc821be40407481fb2a1a..318d8508367cad6ee5290e32d48bfc02710777b6 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2_JIT_STACK_CREATE 3 "23 January 2023" "PCRE2 10.48-RC1"
+.TH PCRE2_JIT_STACK_CREATE 3 "23 January 2023" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
index d8fb298cdf02431bea2ef42ce95424f65b33d574..bd0c6eadb59b51cdc326db5e1153ca9af5b7708e 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2_JIT_STACK_FREE 3 "26 February 2025" "PCRE2 10.48-RC1"
+.TH PCRE2_JIT_STACK_FREE 3 "26 February 2025" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
index 119184219d1adff1f9da10d2cc3335a525ca5457..7efba74c4e0a7d1c686710a8cd1673f18c462fe9 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2_MAKETABLES 3 "26 February 2025" "PCRE2 10.48-RC1"
+.TH PCRE2_MAKETABLES 3 "26 February 2025" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
index 819a6b68167748df4a1010d92c0fc41851d73a1b..9031c99dba44bdc7b6ef32bff6ca4bded51feae5 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2_MAKETABLES_FREE 3 "03 September 2019" "PCRE2 10.48-RC1"
+.TH PCRE2_MAKETABLES_FREE 3 "03 September 2019" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
index 69c31f14b3fc7c7f7e695be785b690b5f581a731..4fe04fffde7613de3d7ef2e69cb667bf690e21d8 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2_MATCH 3 "27 January 2024" "PCRE2 10.48-RC1"
+.TH PCRE2_MATCH 3 "27 January 2024" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
index d35153fffa3d04c9828a7b80431c608d54c8abd9..381391ff6503ac649c6862a08d4af99fed83caaa 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2_MATCH_CONTEXT_COPY 3 "25 October 2014" "PCRE2 10.48-RC1"
+.TH PCRE2_MATCH_CONTEXT_COPY 3 "25 October 2014" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
index e616453fcc796d20203627381f8c1104051f23a8..94887bb42162c042121ee59e7bb0f82c05f80fb7 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2_MATCH_CONTEXT_CREATE 3 "25 October 2014" "PCRE2 10.48-RC1"
+.TH PCRE2_MATCH_CONTEXT_CREATE 3 "25 October 2014" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
index 93844b0f25614ff22442de49b6394d307c222e61..199f7e1bcbe3fd538cf0f886f7146b63bd75d98a 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2_MATCH_CONTEXT_FREE 3 "28 June 2018" "PCRE2 10.48-RC1"
+.TH PCRE2_MATCH_CONTEXT_FREE 3 "28 June 2018" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
index ca8aad6c2173c4d20233cf14ea363d4c3339aa33..068cefedb5b8f897d52a15c35140f270648b0dec 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2_MATCH_DATA_CREATE 3 "28 August 2021" "PCRE2 10.48-RC1"
+.TH PCRE2_MATCH_DATA_CREATE 3 "28 August 2021" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
index c9d949586d3657fe37c0ab830d70dee487dd9a36..10eb594eda69a557eddbbaca9a4589afb81276be 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2_MATCH_DATA_CREATE_FROM_PATTERN 3 "11 August 2025" "PCRE2 10.48-RC1"
+.TH PCRE2_MATCH_DATA_CREATE_FROM_PATTERN 3 "11 August 2025" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
index 9cf7f5ce589e96fc240716da1aed00c4ae83bffe..6e2d8dc49fd74190aac4c8cbb73ef32953b274cc 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2_MATCH_DATA_FREE 3 "16 August 2023" "PCRE2 10.48-RC1"
+.TH PCRE2_MATCH_DATA_FREE 3 "16 August 2023" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
index b38eba3ddcba6f1778890a11f712623041ceaf9c..44da3d2526abb129aba64c2dd6ea249b9230abe6 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2_NEXT_MATCH 3 "24 March 2025" "PCRE2 10.48-RC1"
+.TH PCRE2_NEXT_MATCH 3 "24 March 2025" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
index 41f45e7fd06a00a8bd6609598a80d2f5578558f2..d6f3c68a15403993917824a4135c7e63d504075c 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2_PATTERN_CONVERT 3 "12 July 2017" "PCRE2 10.48-RC1"
+.TH PCRE2_PATTERN_CONVERT 3 "12 July 2017" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
index c40328e1b3b13482a44557d805f94df19f4635f4..51d40f32df77aba7f8c943aaa326f3a926f11e4a 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2_PATTERN_INFO 3 "14 February 2019" "PCRE2 10.48-RC1"
+.TH PCRE2_PATTERN_INFO 3 "14 February 2019" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
index 2a9e401d6c4fed85b687f07c1a6407942c70c176..9e4af0cf8499eac7fedb16d30507de8f46ef2229 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2_SERIALIZE_DECODE 3 "22 April 2022" "PCRE2 10.48-RC1"
+.TH PCRE2_SERIALIZE_DECODE 3 "22 April 2022" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
index 0fff1744a6159eabeb30a1b5fdcc354d848dab7f..e5d8ae69583b6b2cb65a30a5e90594d9af537db1 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2_SERIALIZE_ENCODE 3 "13 August 2018" "PCRE2 10.48-RC1"
+.TH PCRE2_SERIALIZE_ENCODE 3 "13 August 2018" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
index ec1d68dacfc030e478366da2682b47b253ca9b92..545d865d915d1224bff39a0dedc1490fc5c29322 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2_SERIALIZE_FREE 3 "13 August 2018" "PCRE2 10.48-RC1"
+.TH PCRE2_SERIALIZE_FREE 3 "13 August 2018" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
index 35329e96eca088e864942ad976fa74ee6ae2781f..ea76daa0c0fcf5fbeda38dae834ca17c043ac5c6 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2_SERIALIZE_GET_NUMBER_OF_CODES 3 "13 August 2018" "PCRE2 10.48-RC1"
+.TH PCRE2_SERIALIZE_GET_NUMBER_OF_CODES 3 "13 August 2018" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
index 71e7756ad4d3923ae72eee7ed56d26b35667ce76..1d2b0decc47972d8da68d044acf6cf0119a1c594 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2_SET_BSR 3 "25 October 2014" "PCRE2 10.48-RC1"
+.TH PCRE2_SET_BSR 3 "25 October 2014" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
index 4d2090d9cf0404d03f0ef2d85ea918414f32fd29..7b20d9f6da8ff3df966c21c7b3c0a1780be557a3 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2_SET_CALLOUT 3 "25 March 2017" "PCRE2 10.48-RC1"
+.TH PCRE2_SET_CALLOUT 3 "25 March 2017" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
index 4e173996fedc389705cd737492f66a9e7c51b462..a57041c67c2b3ad88d0b12ded78dba1551785f10 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2_SET_CHARACTER_TABLES 3 "15 April 2020" "PCRE2 10.48-RC1"
+.TH PCRE2_SET_CHARACTER_TABLES 3 "15 April 2020" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
index d1d414b7451c7457439e90640ec63c71f6bf86cb..d1eb8d30f371aa1b7fef8b73ef1969559b1d315d 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2_SET_COMPILE_EXTRA_OPTIONS 3 "14 October 2024" "PCRE2 10.48-RC1"
+.TH PCRE2_SET_COMPILE_EXTRA_OPTIONS 3 "14 October 2024" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
index de03c25c5af3f5e6dd0eee58c645602268d0b7a9..a6c80be13082d320b9a8c51e6f3d06655be6721d 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2_SET_COMPILE_RECURSION_GUARD 3 "26 November 2014" "PCRE2 10.48-RC1"
+.TH PCRE2_SET_COMPILE_RECURSION_GUARD 3 "26 November 2014" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
index 7203f1cc5681281e1caf5461be7f2c7058881b8a..59857b88eaa84d438212eccb637003b7cd186c2a 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2_SET_DEPTH_LIMIT 3 "25 March 2017" "PCRE2 10.48-RC1"
+.TH PCRE2_SET_DEPTH_LIMIT 3 "25 March 2017" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
index 93cbcd4ed8e1d828bd04f17a6e56f6f89779c355..73ef5c9c6730b2ed2089ac06d683d333e9c74949 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2_SET_GLOB_ESCAPE 3 "12 July 2017" "PCRE2 10.48-RC1"
+.TH PCRE2_SET_GLOB_ESCAPE 3 "12 July 2017" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
index bafbe887526b58de13780c86eb26dece6cf81c47..cba2042d790d5734ffb7d4f940c5e1dd441376c2 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2_SET_GLOB_SEPARATOR 3 "17 June 2018" "PCRE2 10.48-RC1"
+.TH PCRE2_SET_GLOB_SEPARATOR 3 "17 June 2018" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
index 5cfc7148b99d27e1d78d148642b9d0b3708fdebc..c5fa2ddd6acf68be665406f720d3d5cb4f137666 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2_SET_HEAP_LIMIT 3 "17 June 2018" "PCRE2 10.48-RC1"
+.TH PCRE2_SET_HEAP_LIMIT 3 "17 June 2018" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
index 5e809ad9bb6cc75c17d354d3ca7286554290c902..4c1da55acc913e43ecff5f49c83be758b868399c 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2_SET_MATCH_LIMIT 3 "25 October 2014" "PCRE2 10.48-RC1"
+.TH PCRE2_SET_MATCH_LIMIT 3 "25 October 2014" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
index d931821a2ed506efbbd065ca6c74dec8c22917dd..93c389bdbd62b1fbba8dd8c34aa89acfd277ec70 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2_SET_MAX_PATTERN_COMPILED_LENGTH 3 "09 June 2024" "PCRE2 10.48-RC1"
+.TH PCRE2_SET_MAX_PATTERN_COMPILED_LENGTH 3 "09 June 2024" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
index be5b388323f29312eb7d4c9185eb450a3933fa2e..3946e91483032dde7b85a6d7edb742be7064666a 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2_SET_MAX_PATTERN_LENGTH 3 "05 October 2016" "PCRE2 10.48-RC1"
+.TH PCRE2_SET_MAX_PATTERN_LENGTH 3 "05 October 2016" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
index 98d9f917331bde7609dad6bde9afd4a32d38e94f..a3aa86db3995903e6975611d24fe555a9a8b31be 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2_SET_NEWLINE 3 "11 August 2023" "PCRE2 10.48-RC1"
+.TH PCRE2_SET_NEWLINE 3 "11 August 2023" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
index f22713826f2ab879af9aafacfafcff79e5696ae7..5668767b8561c2564a305abaaf359ae355d535d8 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2_SET_NEWLINE 3 "19 July 2017" "PCRE2 10.48-RC1"
+.TH PCRE2_SET_NEWLINE 3 "19 July 2017" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
index 19476c05e1f3b574d5e071a9a9a3b390bd33adcd..02ebb33e22f51a166913b9d4c033ecc32e748602 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2_SET_OFFSET_LIMIT 3 "22 September 2015" "PCRE2 10.48-RC1"
+.TH PCRE2_SET_OFFSET_LIMIT 3 "22 September 2015" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
index 12ae23a7c17933984cd862943c704994d930cb90..181f268ea632a8673cda9cdff95fb50f59a68b93 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2_SET_OPTIMIZE 3 "22 September 2024" "PCRE2 10.48-RC1"
+.TH PCRE2_SET_OPTIMIZE 3 "22 September 2024" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
index 3103ffd64f8a4eb59077df7a0c983805a94696e7..910bd5c16c75d122f16679581bf48e2514aa1d58 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2_SET_PARENS_NEST_LIMIT 3 "25 October 2014" "PCRE2 10.48-RC1"
+.TH PCRE2_SET_PARENS_NEST_LIMIT 3 "25 October 2014" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
index c5e581749a5ef66d456c20fc634f8e02dc0e6c4b..8138dd52fb65e11abd344f8f89d6de4233a175db 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2_SET_RECURSION_LIMIT 3 "19 July 2017" "PCRE2 10.48-RC1"
+.TH PCRE2_SET_RECURSION_LIMIT 3 "19 July 2017" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
index 2de1ac6cfc17c08c63d402d462bd75250e2b633f..a0bb4af5a10523404f063c804e218541a88fdbe4 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2_SET_RECURSION_MEMORY_MANAGEMENT 3 "23 January 2023" "PCRE2 10.48-RC1"
+.TH PCRE2_SET_RECURSION_MEMORY_MANAGEMENT 3 "23 January 2023" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
index 819e0a1fb477c4b00e6ce4b420f0eb671748697c..80917f0f1e37b73605b0ffd5db4ab3fd4f7f91ed 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2_SET_SUBSTITUTE_CALLOUT 3 "04 October 2024" "PCRE2 10.48-RC1"
+.TH PCRE2_SET_SUBSTITUTE_CALLOUT 3 "04 October 2024" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
index 1ede07b44b242b78e83c9c11b450a81e09df1f69..b52fbe8d3c07dc910ba8ac5c575f0164cc988f9f 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2_SET_SUBSTITUTE_CASE_CALLOUT 3 "26 December 2024" "PCRE2 10.48-RC1"
+.TH PCRE2_SET_SUBSTITUTE_CASE_CALLOUT 3 "26 December 2024" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
index 666a1870b3f5fc879438d44a6f914f51b34cc052..1bc8aa94ac429244ee3410706316242936b37d3b 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2_SUBSTITUTE 3 "03 October 2025" "PCRE2 10.48-RC1"
+.TH PCRE2_SUBSTITUTE 3 "03 October 2025" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
index 24d986ba92a4ef8ffb4f6c391bea5fc869f4360f..1fade5488376ac4b3bf73179c4768219e2045776 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2_SUBSTRING_COPY_BYNAME 3 "19 December 2014" "PCRE2 10.48-RC1"
+.TH PCRE2_SUBSTRING_COPY_BYNAME 3 "19 December 2014" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
index f8fcb7abfe565e78258788efe5538661d4fc2a56..11f37779ba316b86f9c1710f964af17695c51155 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2_SUBSTRING_COPY_BYNUMBER 3 "13 December 2014" "PCRE2 10.48-RC1"
+.TH PCRE2_SUBSTRING_COPY_BYNUMBER 3 "13 December 2014" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
index 10c5377b212ddd7da6480c7f70fc5a947464cf1a..58ae037bf8cbc31c9b3d3982bf901b50b709e85b 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2_SUBSTRING_FREE 3 "26 February 2025" "PCRE2 10.48-RC1"
+.TH PCRE2_SUBSTRING_FREE 3 "26 February 2025" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
index ccdddd9e3e35c07539c76dff2b2e7d79b6b75561..a84140322e38f1a7e48fb1605024302b472a72b0 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2_SUBSTRING_GET_BYNAME 3 "19 December 2014" "PCRE2 10.48-RC1"
+.TH PCRE2_SUBSTRING_GET_BYNAME 3 "19 December 2014" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
index d7fd8be8c3179f60c69df43114acefd255d9c888..1efe1e2306f136c1b5ddf1141afea17627b93b65 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2_SUBSTRING_GET_BYNUMBER 3 "13 December 2014" "PCRE2 10.48-RC1"
+.TH PCRE2_SUBSTRING_GET_BYNUMBER 3 "13 December 2014" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
index cbb442890c6690856e677ac7e82fd7c0f27b0fa3..1c3815f3664790c4e39d5431b9984b045066bc03 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2_SUBSTRING_LENGTH_BYNAME 3 "26 September 2025" "PCRE2 10.48-RC1"
+.TH PCRE2_SUBSTRING_LENGTH_BYNAME 3 "26 September 2025" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
index 150395743e5e2564c6c746b7dff1fc77b2d26877..0c81f55c294387c49d61be18511708708369c58d 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2_SUBSTRING_LENGTH_BYNUMBER 3 "22 December 2014" "PCRE2 10.48-RC1"
+.TH PCRE2_SUBSTRING_LENGTH_BYNUMBER 3 "22 December 2014" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
index c31e5e503b98bcd407dcaeacec3947d972cca137..a17712e8e6d9098fb4d6db8f53c7d028915a05fc 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2_SUBSTRING_LIST_FREE 3 "26 February 2025" "PCRE2 10.48-RC1"
+.TH PCRE2_SUBSTRING_LIST_FREE 3 "26 February 2025" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
index 9a5db54325a1fa2c4116b2f9545a034e48b789a3..b7868d071e01a4a1e5bff6047a9fee987fc3ba25 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2_SUBSTRING_LIST_GET 3 "21 October 2014" "PCRE2 10.48-RC1"
+.TH PCRE2_SUBSTRING_LIST_GET 3 "21 October 2014" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
index 0898b0b85841f80c42039ed9f9893413c089e187..849d8275dc0b08bb0d426f862e650c76046f3e36 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2_SUBSTRING_NAMETABLE_SCAN 3 "06 February 2019" "PCRE2 10.48-RC1"
+.TH PCRE2_SUBSTRING_NAMETABLE_SCAN 3 "06 February 2019" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
index e5aa7f9d45ccd3ada4a4c1c54776745790e5ae4a..bbd140071964c2aa5c67182a92640fe5a432b2ba 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2_SUBSTRING_NUMBER_FROM_NAME 3 "03 November 2014" "PCRE2 10.48-RC1"
+.TH PCRE2_SUBSTRING_NUMBER_FROM_NAME 3 "03 November 2014" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
index f3df177905a9da3a2861f93ca10b23596b6d3bf0..8d49818df291d187331af0b342b38ba0b47706e0 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2API 3 "08 December 2025" "PCRE2 10.48-RC1"
+.TH PCRE2API 3 "08 December 2025" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .sp
index fa1212155032942ba110ebd1aee687ba651fe012..1b9b712186bed52dd58b3d64d189f376041b0db6 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2BUILD 3 "17 October 2025" "PCRE2 10.48-RC1"
+.TH PCRE2BUILD 3 "17 October 2025" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .
index f1bacb84eb2deb73772b2953c9b7fa280454c407..a00ecf502ffc80fcc3dfb05837f877f38f8bed3a 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2CALLOUT 3 "26 February 2025" "PCRE2 10.48-RC1"
+.TH PCRE2CALLOUT 3 "26 February 2025" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
index 3ea2881332a453be4884e5fcc9f19653b1767740..9435a9d16a6e70ce00e21722b7254005d09ab4e2 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2COMPAT 3 "02 June 2025" "PCRE2 10.48-RC1"
+.TH PCRE2COMPAT 3 "02 June 2025" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH "DIFFERENCES BETWEEN PCRE2 AND PERL"
index ac1495b2d2dffa9522b7b3ec3c852c9cfe185045..d227f476367e51b7fc11826c87caf3fc1f1b457c 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2CONVERT 3 "14 November 2023" "PCRE2 10.48-RC1"
+.TH PCRE2CONVERT 3 "14 November 2023" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH "EXPERIMENTAL PATTERN CONVERSION FUNCTIONS"
index 2d258aff579828c5dea091d382b178edab659dd4..b4a360ff978a6adf48ae16f275d56caeb7aabe5c 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2DEMO 3 "24 March 2025" "PCRE2 10.48-RC1"
+.TH PCRE2DEMO 3 "24 March 2025" "PCRE2 10.48"
 .\"AUTOMATICALLY GENERATED BY UpdateAlways - do not EDIT!
 .SH NAME
 PCRE2DEMO - A demonstration C program for PCRE2
index d7104bbe128f1ae81d60b1ec727e37866029ddf7..ab57cad0e7672e6f758ca9b1d3bdba317d1cad81 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2GREP 1 "24 January 2025" "PCRE2 10.48-RC1"
+.TH PCRE2GREP 1 "24 January 2025" "PCRE2 10.48"
 .SH NAME
 pcre2grep - a grep with Perl-compatible regular expressions.
 .SH SYNOPSIS
index 484275545f37b5900445e14660545d62a9063d53..99f14abdec4091ebf709f48771d415ffb75aeb77 100644 (file)
@@ -1103,4 +1103,4 @@ REVISION
        Copyright (c) 1997-2023 University of Cambridge.
 
 
-PCRE2 10.48-RC1                 24 January 2025                   PCRE2GREP(1)
+PCRE2 10.48                     24 January 2025                   PCRE2GREP(1)
index 23dcb91a2d04375bcd8b436c63f1415ee2c52b9a..947cd41475b29d3a8ad5263e62641f64af282395 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2JIT 3 "08 August 2026" "PCRE2 10.48-RC1"
+.TH PCRE2JIT 3 "08 August 2026" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH "PCRE2 JUST-IN-TIME COMPILER SUPPORT"
index 9b8e6a6265468bda8e83bf305f2fc47f97f9418e..03c1ee97066fc0e4919279c986a23f1181c281d9 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2LIMITS 3 "03 September 2025" "PCRE2 10.48-RC1"
+.TH PCRE2LIMITS 3 "03 September 2025" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH "SIZE AND OTHER LIMITATIONS"
index 23f6eb4be3f048a4a8e26b86c434913fcb6a09be..7d5b04bf2e3a0fd2081855356be18f5d45551b41 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2MATCHING 3 "22 February 2025" "PCRE2 10.48-RC1"
+.TH PCRE2MATCHING 3 "22 February 2025" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH "PCRE2 MATCHING ALGORITHMS"
index b55630e809caa7cb9ceb707d02a0d1cb4801fafe..2b7ad09fb16de98e9f9cc200872634f7aba46207 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2PARTIAL 3 "16 August 2026" "PCRE2 10.48-RC1"
+.TH PCRE2PARTIAL 3 "16 August 2026" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH "PARTIAL MATCHING IN PCRE2"
index 489adc3ffddb794ad81cc41f21eba352a4497393..ad946b45272220c38e41dc8893d0a511f3efb330 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2PATTERN 3 "25 October 2025" "PCRE2 10.48-RC1"
+.TH PCRE2PATTERN 3 "25 October 2025" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH "PCRE2 REGULAR EXPRESSION DETAILS"
index 1a8c2b56bac30d27e8466bca0a395b3682559421..bec85fe4ae622e858a890771031c02e2ceed1de4 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2PERFORM 3 "06 December 2022" "PCRE2 10.48-RC1"
+.TH PCRE2PERFORM 3 "06 December 2022" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH "PCRE2 PERFORMANCE"
index 59cfb77ba2cd38de6e933efef04f1cd3f3445131..e788bd46fe00da30d7fb2efa0c78bb42802eda20 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2POSIX 3 "27 November 2024" "PCRE2 10.48-RC1"
+.TH PCRE2POSIX 3 "27 November 2024" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH "SYNOPSIS"
index 84a8c87bb43597e033ffcab09218f5afee41cddf..f931df247a994a38ae1ee91aa6148210c5391564 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2SAMPLE 3 "28 February 2025" "PCRE2 10.48-RC1"
+.TH PCRE2SAMPLE 3 "28 February 2025" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH "PCRE2 SAMPLE PROGRAM"
index 758e887d2343f7ed46fc6411129585ab3244dc47..46e75a70c29f22e5bcc63e6fee815cddaa53032f 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2SERIALIZE 3 "19 January 2024" "PCRE2 10.48-RC1"
+.TH PCRE2SERIALIZE 3 "19 January 2024" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH "SAVING AND RE-USING PRECOMPILED PCRE2 PATTERNS"
index b9f23dfdf5ada42d5d22929aa86cee9d5fe25432..c3a68bd646d334303905beced5c69b9e08176730 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2SYNTAX 3 "14 October 2025" "PCRE2 10.48-RC1"
+.TH PCRE2SYNTAX 3 "14 October 2025" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH "PCRE2 REGULAR EXPRESSION SYNTAX SUMMARY"
index f66af14494d52115528ac8b5ab4a313bab33a658..405578d31361d17474f15d980fd53a6b431d2ab1 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2TEST 1 "22 August 2026" "PCRE2 10.48-RC1"
+.TH PCRE2TEST 1 "22 August 2026" "PCRE2 10.48"
 .SH NAME
 pcre2test - a program for testing Perl-compatible regular expressions.
 .SH SYNOPSIS
index 5dc42f12f3c7e792cbd79e2d1c88a607170d1bd9..e0e85540679900f340f95af0caadb0bd7a8a6554 100644 (file)
@@ -2104,4 +2104,4 @@ REVISION
        Copyright (c) 1997-2024 University of Cambridge.
 
 
-PCRE2 10.48-RC1                 22 August 2026                    PCRE2TEST(1)
+PCRE2 10.48                     22 August 2026                    PCRE2TEST(1)
index e6cda0a962bfe88dd3ac8eb68db5181b1bc7d04a..c6bb26e7ab6bf555b101f83b538e338990a0e32a 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2UNICODE 3 "27 November 2024" "PCRE2 10.48-RC1"
+.TH PCRE2UNICODE 3 "27 November 2024" "PCRE2 10.48"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH "UNICODE AND UTF SUPPORT"
index 22b50c0514cfec072d240f6106a4c5e552913539..a5f9d447040b19b8ef3b9257b3b8d1d7012a1331 100644 (file)
@@ -4,10 +4,321 @@ Date:   Tue Apr 27 08:36:47 2021 +0000
 
     Remove real POSIX function names from the pcre2-posix library.
 
+diff --git a/ChangeLog b/ChangeLog
+index 5d64b35d..6bc766dc 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -11,13 +11,13 @@ with binary zeros. This is from Bugzilla #2681. Patch from Jeremie
+ Courreges-Anglas via Nam Nguyen. This fixes RunGrepTest for OpenBSD. Later: 
+ it broke it for at least one version of Solaris, where tr can't handle binary 
+ zeros. However, that system had /usr/xpg4/bin/tr installed, which works OK, so 
+-RunGrepTest now checks for that command and use it if found.
++RunGrepTest now checks for that command and uses it if found.
+ 2. Compiling with gcc 10.2's -fanalyzer option showed up a hypothetical problem 
+ with a NULL dereference. I don't think this case could ever occur in practice, 
+ but I have put in a check in order to get rid of the compiler error.
+-3. An alternative patch for CMakeLists.txt because 10.36 # 4 breaks CMake on
++3. An alternative patch for CMakeLists.txt because 10.36 #4 breaks CMake on
+ Windows. Patch from email@cs-ware.de fixes bugzilla #2688.
+ 4. Two bugs related to over-large numbers have been fixed so the behaviour is 
+@@ -44,6 +44,14 @@ recursions such as /(a\K.(?1)*)/ did not have this problem.
+ 7. Restore single character repetition optimization in JIT. Currently fewer
+ character repetitions are optimized than in 10.34.
++8. When the names of the functions in the POSIX wrapper were changed to
++pcre2_regcomp() etc. (see change 10.33 #4 below), functions with the original 
++names were left in the library so that pre-compiled programs would still work. 
++However, this has proved troublesome when programs link with several libraries, 
++some of which use PCRE2 via the POSIX interface while others use a native POSIX 
++library. For this reason, the POSIX function names are removed in this release.
++The macros in pcre2posix.h should ensure that re-compiling fixes any programs 
++that haven't been compiled since before 10.33.
+ Version 10.36 04-December-2020
+diff --git a/doc/html/pcre2posix.html b/doc/html/pcre2posix.html
+index 20a2009b..c54860f9 100644
+--- a/doc/html/pcre2posix.html
++++ b/doc/html/pcre2posix.html
+@@ -68,11 +68,14 @@ application. Because the POSIX functions call the native ones, it is also
+ necessary to add <b>-lpcre2-8</b>.
+ </P>
+ <P>
+-Although they are not defined as protypes in <b>pcre2posix.h</b>, the library
+-does contain functions with the POSIX names <b>regcomp()</b> etc. These simply
+-pass their arguments to the PCRE2 functions. These functions are provided for
+-backwards compatibility with earlier versions of PCRE2, so that existing
+-programs do not have to be recompiled.
++Although they were not defined as protypes in <b>pcre2posix.h</b>, releases
++10.33 to 10.36 of the library contained functions with the POSIX names
++<b>regcomp()</b> etc. These simply passed their arguments to the PCRE2
++functions. These functions were provided for backwards compatibility with
++earlier versions of PCRE2, which had only POSIX names. However, this has proved
++troublesome in situations where a program links with several libraries, some of 
++which use PCRE2's POSIX interface while others use the real POSIX functions. 
++For this reason, the POSIX names have been removed since release 10.37.
+ </P>
+ <P>
+ Calling the header file <b>pcre2posix.h</b> avoids any conflict with other POSIX
+@@ -344,9 +347,9 @@ Cambridge, England.
+ </P>
+ <br><a name="SEC10" href="#TOC1">REVISION</a><br>
+ <P>
+-Last updated: 30 January 2019
++Last updated: 26 April 2021
+ <br>
+-Copyright &copy; 1997-2019 University of Cambridge.
++Copyright &copy; 1997-2021 University of Cambridge.
+ <br>
+ <p>
+ Return to the <a href="index.html">PCRE2 index page</a>.
+diff --git a/doc/pcre2.txt b/doc/pcre2.txt
+index 365ecc49..61855f19 100644
+--- a/doc/pcre2.txt
++++ b/doc/pcre2.txt
+@@ -180,8 +180,8 @@ REVISION
+        Last updated: 17 September 2018
+        Copyright (c) 1997-2018 University of Cambridge.
+ ------------------------------------------------------------------------------
+-
+-
++ 
++ 
+ PCRE2API(3)                Library Functions Manual                PCRE2API(3)
+@@ -3829,8 +3829,8 @@ REVISION
+        Last updated: 04 November 2020
+        Copyright (c) 1997-2020 University of Cambridge.
+ ------------------------------------------------------------------------------
+-
+-
++ 
++ 
+ PCRE2BUILD(3)              Library Functions Manual              PCRE2BUILD(3)
+@@ -4423,8 +4423,8 @@ REVISION
+        Last updated: 20 March 2020
+        Copyright (c) 1997-2020 University of Cambridge.
+ ------------------------------------------------------------------------------
+-
+-
++ 
++ 
+ PCRE2CALLOUT(3)            Library Functions Manual            PCRE2CALLOUT(3)
+@@ -4853,8 +4853,8 @@ REVISION
+        Last updated: 03 February 2019
+        Copyright (c) 1997-2019 University of Cambridge.
+ ------------------------------------------------------------------------------
+-
+-
++ 
++ 
+ PCRE2COMPAT(3)             Library Functions Manual             PCRE2COMPAT(3)
+@@ -5066,8 +5066,8 @@ REVISION
+        Last updated: 06 October 2020
+        Copyright (c) 1997-2019 University of Cambridge.
+ ------------------------------------------------------------------------------
+-
+-
++ 
++ 
+ PCRE2JIT(3)                Library Functions Manual                PCRE2JIT(3)
+@@ -5491,8 +5491,8 @@ REVISION
+        Last updated: 23 May 2019
+        Copyright (c) 1997-2019 University of Cambridge.
+ ------------------------------------------------------------------------------
+-
+-
++ 
++ 
+ PCRE2LIMITS(3)             Library Functions Manual             PCRE2LIMITS(3)
+@@ -5561,8 +5561,8 @@ REVISION
+        Last updated: 02 February 2019
+        Copyright (c) 1997-2019 University of Cambridge.
+ ------------------------------------------------------------------------------
+-
+-
++ 
++ 
+ PCRE2MATCHING(3)           Library Functions Manual           PCRE2MATCHING(3)
+@@ -5785,8 +5785,8 @@ REVISION
+        Last updated: 23 May 2019
+        Copyright (c) 1997-2019 University of Cambridge.
+ ------------------------------------------------------------------------------
+-
+-
++ 
++ 
+ PCRE2PARTIAL(3)            Library Functions Manual            PCRE2PARTIAL(3)
+@@ -6165,8 +6165,8 @@ REVISION
+        Last updated: 04 September 2019
+        Copyright (c) 1997-2019 University of Cambridge.
+ ------------------------------------------------------------------------------
+-
+-
++ 
++ 
+ PCRE2PATTERN(3)            Library Functions Manual            PCRE2PATTERN(3)
+@@ -9613,8 +9613,8 @@ REVISION
+        Last updated: 06 October 2020
+        Copyright (c) 1997-2020 University of Cambridge.
+ ------------------------------------------------------------------------------
+-
+-
++ 
++ 
+ PCRE2PERFORM(3)            Library Functions Manual            PCRE2PERFORM(3)
+@@ -9848,8 +9848,8 @@ REVISION
+        Last updated: 03 February 2019
+        Copyright (c) 1997-2019 University of Cambridge.
+ ------------------------------------------------------------------------------
+-
+-
++ 
++ 
+ PCRE2POSIX(3)              Library Functions Manual              PCRE2POSIX(3)
+@@ -9895,11 +9895,15 @@ DESCRIPTION
+        an application. Because the POSIX functions call the native ones, it is
+        also necessary to add -lpcre2-8.
+-       Although  they are not defined as protypes in pcre2posix.h, the library
+-       does contain functions with the POSIX names regcomp() etc. These simply
+-       pass  their  arguments to the PCRE2 functions. These functions are pro-
+-       vided for backwards compatibility with earlier versions  of  PCRE2,  so
+-       that existing programs do not have to be recompiled.
++       Although  they  were  not defined as protypes in pcre2posix.h, releases
++       10.33 to 10.36 of the library contained functions with the POSIX  names
++       regcomp()  etc.  These simply passed their arguments to the PCRE2 func-
++       tions. These functions were provided for backwards  compatibility  with
++       earlier  versions  of  PCRE2, which had only POSIX names. However, this
++       has proved troublesome in situations where a program links with several
++       libraries,  some  of which use PCRE2's POSIX interface while others use
++       the real POSIX functions.  For this reason, the POSIX names  have  been
++       removed since release 10.37.
+        Calling  the  header  file  pcre2posix.h avoids any conflict with other
+        POSIX libraries. It can, of course, be renamed or aliased  as  regex.h,
+@@ -10175,11 +10179,11 @@ AUTHOR
+ REVISION
+-       Last updated: 30 January 2019
+-       Copyright (c) 1997-2019 University of Cambridge.
++       Last updated: 26 April 2021
++       Copyright (c) 1997-2021 University of Cambridge.
+ ------------------------------------------------------------------------------
+-
+-
++ 
++ 
+ PCRE2SAMPLE(3)             Library Functions Manual             PCRE2SAMPLE(3)
+@@ -10457,8 +10461,8 @@ REVISION
+        Last updated: 27 June 2018
+        Copyright (c) 1997-2018 University of Cambridge.
+ ------------------------------------------------------------------------------
+-
+-
++ 
++ 
+ PCRE2SYNTAX(3)             Library Functions Manual             PCRE2SYNTAX(3)
+@@ -10973,8 +10977,8 @@ REVISION
+        Last updated: 28 December 2019
+        Copyright (c) 1997-2019 University of Cambridge.
+ ------------------------------------------------------------------------------
+-
+-
++ 
++ 
+ PCRE2UNICODE(3)            Library Functions Manual            PCRE2UNICODE(3)
+@@ -11408,5 +11412,5 @@ REVISION
+        Last updated: 23 February 2020
+        Copyright (c) 1997-2020 University of Cambridge.
+ ------------------------------------------------------------------------------
+-
+-
++ 
++ 
+diff --git a/doc/pcre2posix.3 b/doc/pcre2posix.3
+index 35e68e2d..a470c8f9 100644
+--- a/doc/pcre2posix.3
++++ b/doc/pcre2posix.3
+@@ -1,4 +1,4 @@
+-.TH PCRE2POSIX 3 "30 January 2019" "PCRE2 10.33"
++.TH PCRE2POSIX 3 "26 April 2021" "PCRE2 10.37"
+ .SH NAME
+ PCRE2 - Perl-compatible regular expressions (revised API)
+ .SH "SYNOPSIS"
+@@ -44,11 +44,14 @@ can be accessed by adding \fB-lpcre2-posix\fP to the command for linking an
+ application. Because the POSIX functions call the native ones, it is also
+ necessary to add \fB-lpcre2-8\fP.
+ .P
+-Although they are not defined as protypes in \fBpcre2posix.h\fP, the library
+-does contain functions with the POSIX names \fBregcomp()\fP etc. These simply
+-pass their arguments to the PCRE2 functions. These functions are provided for
+-backwards compatibility with earlier versions of PCRE2, so that existing
+-programs do not have to be recompiled.
++Although they were not defined as protypes in \fBpcre2posix.h\fP, releases
++10.33 to 10.36 of the library contained functions with the POSIX names
++\fBregcomp()\fP etc. These simply passed their arguments to the PCRE2
++functions. These functions were provided for backwards compatibility with
++earlier versions of PCRE2, which had only POSIX names. However, this has proved
++troublesome in situations where a program links with several libraries, some of 
++which use PCRE2's POSIX interface while others use the real POSIX functions. 
++For this reason, the POSIX names have been removed since release 10.37.
+ .P
+ Calling the header file \fBpcre2posix.h\fP avoids any conflict with other POSIX
+ libraries. It can, of course, be renamed or aliased as \fBregex.h\fP, which is
+@@ -321,6 +324,6 @@ Cambridge, England.
+ .rs
+ .sp
+ .nf
+-Last updated: 30 January 2019
+-Copyright (c) 1997-2019 University of Cambridge.
++Last updated: 26 April 2021
++Copyright (c) 1997-2021 University of Cambridge.
+ .fi
 diff --git a/src/pcre2posix.c b/src/pcre2posix.c
 index b24620a4..32c80c3f 100644
 --- a/src/pcre2posix.c
 +++ b/src/pcre2posix.c
+@@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language.
+                        Written by Philip Hazel
+      Original API code Copyright (c) 1997-2012 University of Cambridge
+-          New API code Copyright (c) 2016-2019 University of Cambridge
++          New API code Copyright (c) 2016-2021 University of Cambridge
+ -----------------------------------------------------------------------------
+ Redistribution and use in source and binary forms, with or without
 @@ -175,6 +175,20 @@ static const char *const pstring[] = {
  
  
index 2d89da9782bbda111f5beb4ee167f3d93eb08c1e..ade86bad2c52672528f7496b548fd3a69009e75a 100644 (file)
@@ -4,11 +4,26 @@ Date:   Thu Mar 24 05:34:42 2022 +0000
 
     Fix incorrect value reading in JIT.
 
+diff --git a/src/pcre2_jit_compile.c b/src/pcre2_jit_compile.c
+index 94f6a588..7fcdac86 100644
+--- a/src/pcre2_jit_compile.c
++++ b/src/pcre2_jit_compile.c
+@@ -7489,7 +7489,7 @@ while (*cc != XCL_END)
+     {
+     SLJIT_ASSERT(*cc == XCL_PROP || *cc == XCL_NOTPROP);
+     cc++;
+-    if (*cc == PT_CLIST && *cc == XCL_PROP)
++    if (*cc == PT_CLIST && cc[-1] == XCL_PROP)
+       {
+       other_cases = PRIV(ucd_caseless_sets) + cc[1];
+       while (*other_cases != NOTACHAR)
+
 commit 50a51cb7e67268e6ad417eb07c9de9bfea5cc55a
 Author: Zoltan Herczeg <hzmester@freemail.hu>
 Date:   Wed Mar 23 07:53:25 2022 +0000
 
     Fixed a unicode properrty matching issue in JIT
+
 diff --git a/ChangeLog b/ChangeLog
 index f0eab7ba..ffb08805 100644
 --- a/ChangeLog
@@ -24,7 +39,7 @@ index f0eab7ba..ffb08805 100644
  Version 10.39 29-October-2021
  -----------------------------
 diff --git a/src/pcre2_jit_compile.c b/src/pcre2_jit_compile.c
-index e7dd26c5..7fcdac86 100644
+index e7dd26c5..94f6a588 100644
 --- a/src/pcre2_jit_compile.c
 +++ b/src/pcre2_jit_compile.c
 @@ -7489,7 +7489,7 @@ while (*cc != XCL_END)
@@ -32,7 +47,7 @@ index e7dd26c5..7fcdac86 100644
      SLJIT_ASSERT(*cc == XCL_PROP || *cc == XCL_NOTPROP);
      cc++;
 -    if (*cc == PT_CLIST)
-+    if (*cc == PT_CLIST && cc[-1] == XCL_PROP)
++    if (*cc == PT_CLIST && *cc == XCL_PROP)
        {
        other_cases = PRIV(ucd_caseless_sets) + cc[1];
        while (*other_cases != NOTACHAR)
index 9a9d0208aeb95aa2e0df3edb4c3a8e593b1a1fca..9eb6b2fa6928d97a183d971d01d9f639547f6d9c 100644 (file)
@@ -1,38 +1,32 @@
-From bfb55a6bd406ae711444915bba957b933aaa10ca Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Carlo=20Marcelo=20Arenas=20Bel=C3=B3n?= <carenas@gmail.com>
-Date: Tue, 17 Jan 2023 06:55:53 -0800
-Subject: [PATCH 1/2] avoid LIMIT_HEAP integer multiplication wrap around
- (#184)
+commit 4d66adc387baa2d29f91f0cadfaf8d8e77e13bb3
+Author: Carlo Marcelo Arenas Belón <carenas@gmail.com>
+Date:   Tue Jan 17 06:55:53 2023 -0800
 
-Cherry-picked from 4d66adc387baa2d29f91f0cadfaf8d8e77e13bb3.
-
-If a LIMIT_HEAP value once converted to bytes is larger than UINT_MAX
-would result in a bogus setting that could trigger a matching failure
-as shown by the following:
-
-  PCRE2 version 10.42 2022-12-11
-    re> /(*LIMIT_HEAP=4194304)a/
-  data> a
-  Failed: error -63: heap limit exceeded
-
-Remove the multiplication and instead keep track of the maximum heap
-allowed in KB as was done originally.
-
-Aditionally, add a check to avoid overflowing a PCRE2_SIZE while
-doubling the heap used and that could result in a crash (only on
-systems with a 32-bit PCRE2_SIZE and using non standard settings).
-
-Unlike the original, this code avoids rounding the heapframes_size
-to the frame_size at the allocation time, which simplifies the logic
-and wasn't really needed.
-
-Fixes: d90fb23 (Refactor match_data() to always use the heap instead
-       of having an initial frames vector on the stack..., 2022-07-27)
-Closes: #183
----
- src/pcre2_intmodedep.h |  4 ++--
- src/pcre2_match.c      | 38 +++++++++++++++++++++++++++-----------
- 2 files changed, 29 insertions(+), 13 deletions(-)
+    avoid LIMIT_HEAP integer multiplication wrap around (#184)
+    
+    If a LIMIT_HEAP value once converted to bytes is larger than UINT_MAX
+    would result in a bogus setting that could trigger a matching failure
+    as shown by the following:
+    
+      PCRE2 version 10.42 2022-12-11
+        re> /(*LIMIT_HEAP=4194304)a/
+      data> a
+      Failed: error -63: heap limit exceeded
+    
+    Remove the multiplication and instead keep track of the maximum heap
+    allowed in KB as was done originally.
+    
+    Aditionally, add a check to avoid overflowing a PCRE2_SIZE while
+    doubling the heap used and that could result in a crash (only on
+    systems with a 32-bit PCRE2_SIZE and using non standard settings).
+    
+    Unlike the original, this code avoids rounding the heapframes_size
+    to the frame_size at the allocation time, which simplifies the logic
+    and wasn't really needed.
+    
+    Fixes: d90fb23 (Refactor match_data() to always use the heap instead
+           of having an initial frames vector on the stack..., 2022-07-27)
+    Closes: #183
 
 diff --git a/src/pcre2_intmodedep.h b/src/pcre2_intmodedep.h
 index 390e737a..8f6487e9 100644
@@ -132,6 +126,3 @@ index 168b9fad..fa49e64a 100644
  
  if (match_data->heapframes_size < heapframes_size)
    {
--- 
-2.51.2.vfs.0.0
-
index e5d59485e6d065b309369d1e976e9a3def8ecbeb..640ddb9ba6cede0c532577b4cd609d0409954bff 100644 (file)
@@ -1,17 +1,27 @@
-From ba0a3ff395d99ab2fe7ee76f96c97736294298c6 Mon Sep 17 00:00:00 2001
-From: Philip Hazel <Philip.Hazel@gmail.com>
-Date: Fri, 18 Aug 2023 17:40:16 +0100
-Subject: [PATCH 2/2] Fix issue #275
+commit 803a64f6151a2d43a44a2377956ae36408c96986
+Author: Philip Hazel <Philip.Hazel@gmail.com>
+Date:   Fri Aug 18 17:40:16 2023 +0100
 
-Cherry-picked from 803a64f6151a2d43a44a2377956ae36408c96986.
----
- src/pcre2_match.c     | 32 +++++++++++++++-----------------
- testdata/testinput15  |  7 ++++++-
- testdata/testoutput15 |  8 +++++++-
- 3 files changed, 28 insertions(+), 19 deletions(-)
+    Fix issue #275
 
+diff --git a/ChangeLog b/ChangeLog
+index e2885418..3d594cd1 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -101,6 +101,11 @@ source-tree CMake build testing.
+ 26. Add support for LoongArch in JIT.
++27. Fixed a bug in pcre2_match() in the code for handling the vector of
++backtracking frames on the heap, which caused a heap overflow if *LIMIT_HEAP
++restricted an attempt to extend to less than the frame size. Generally tidy up
++the code for extending the heap frames vector. This fixes GitHub issue #275.
++
+ Version 10.42 11-December-2022
+ ------------------------------
 diff --git a/src/pcre2_match.c b/src/pcre2_match.c
-index fa49e64a..8d3c796e 100644
+index f69ec0db..5ce17926 100644
 --- a/src/pcre2_match.c
 +++ b/src/pcre2_match.c
 @@ -597,7 +597,6 @@ heapframe *P = NULL;
@@ -22,7 +32,7 @@ index fa49e64a..8d3c796e 100644
  PCRE2_SIZE frame_copy_size;   /* Amount to copy when creating a new frame */
  
  /* Local variables that do not need to be preserved over calls to RRMATCH(). */
-@@ -635,13 +634,10 @@ copied when a new frame is created. */
+@@ -637,13 +636,10 @@ copied when a new frame is created. */
  
  frame_copy_size = frame_size - offsetof(heapframe, eptr);
  
@@ -38,7 +48,7 @@ index fa49e64a..8d3c796e 100644
  
  Frdepth = 0;                        /* "Recursion" depth */
  Fcapture_last = 0;                  /* Number of most recent capture */
-@@ -662,10 +658,11 @@ MATCH_RECURSE:
+@@ -664,10 +660,11 @@ MATCH_RECURSE:
  doubling the size, but constrained by the heap limit (which is in KiB). */
  
  N = (heapframe *)((char *)F + frame_size);
@@ -51,7 +61,7 @@ index fa49e64a..8d3c796e 100644
  
    if (match_data->heapframes_size >= PCRE2_SIZE_MAX / 2)
      {
-@@ -679,7 +676,8 @@ if (N >= frames_top)
+@@ -681,7 +678,8 @@ if (N >= frames_top)
    if (newsize / 1024 >= mb->heap_limit)
      {
      PCRE2_SIZE old_size = match_data->heapframes_size / 1024;
@@ -61,7 +71,7 @@ index fa49e64a..8d3c796e 100644
      else
        {
        PCRE2_SIZE max_delta = 1024 * (mb->heap_limit - old_size);
-@@ -689,19 +687,21 @@ if (N >= frames_top)
+@@ -691,19 +689,21 @@ if (N >= frames_top)
        }
      }
  
@@ -89,7 +99,7 @@ index fa49e64a..8d3c796e 100644
    }
  
  #ifdef DEBUG_SHOW_RMATCH
-@@ -6842,8 +6842,7 @@ mb->match_limit_depth = (mcontext->depth_limit < re->limit_depth)?
+@@ -6935,8 +6935,7 @@ mb->match_limit_depth = (mcontext->depth_limit < re->limit_depth)?
  /* If a pattern has very many capturing parentheses, the frame size may be very
  large. Set the initial frame vector size to ensure that there are at least 10
  available frames, but enforce a minimum of START_FRAMES_SIZE. If this is
@@ -99,7 +109,7 @@ index fa49e64a..8d3c796e 100644
  
  heapframes_size = frame_size * 10;
  if (heapframes_size < START_FRAMES_SIZE) heapframes_size = START_FRAMES_SIZE;
-@@ -7301,7 +7300,6 @@ for(;;)
+@@ -7394,7 +7393,6 @@ for(;;)
    mb->match_call_count = 0;
    mb->end_offset_top = 0;
    mb->skip_arg_count = 0;
@@ -155,6 +165,3 @@ index af0d7c2a..be7afd0f 100644
  /(a+)*zz/I
  Capture group count = 1
  Starting code units: a z 
--- 
-2.51.2.vfs.0.0
-
index 6b951f99b30b49866b7393b8da5c9f333b5a1e65..5b6ca9491e0080ce5a24bd5031a74808f9da13fe 100644 (file)
@@ -1,22 +1,35 @@
-From 0d7159ca52771daa8b5cafc422b6c140aa7a11d7 Mon Sep 17 00:00:00 2001
-From: Philip Hazel <Philip.Hazel@gmail.com>
-Date: Fri, 1 Mar 2024 17:23:34 +0000
-Subject: [PATCH] Fix incorrect compiling when variable-length lookbehind's
- first branch was not the shortest and there was a backreference to a
- groupwithin the lookbehind.
+commit 4a6a8b056f39079d5e958eac84c2ad173f4680bc
+Author: Philip Hazel <Philip.Hazel@gmail.com>
+Date:   Fri Mar 1 17:23:34 2024 +0000
 
-Cherry-picked from 4a6a8b056f39079d5e958eac84c2ad173f4680bc.
----
- src/pcre2_compile.c  |  2 +-
- testdata/testinput2  |  4 ++++
- testdata/testoutput2 | 10 ++++++++++
- 3 files changed, 15 insertions(+), 1 deletion(-)
+    Fix incorrect compiling when variable-length lookbehind's first branch was not the shortest and there was a backreference to a groupwithin the lookbehind.
 
+diff --git a/ChangeLog b/ChangeLog
+index 0568108a..6b78659e 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -4,6 +4,16 @@ Change Log for PCRE2
+ Before the move to GitHub, this was the only record of changes to PCRE2. Now
+ there is often more detail in the pull requests.
++Version 10.44 xx-xxx-2024
++-------------------------
++
++1. If a pattern contained a variable-length lookbehind in which the first 
++branch was not the one with the shortest minimym length, and the lookbehind 
++contained a capturing group, and elsewhere in the pattern there was another 
++lookbehind that referenced that group, the pattern was incorrectly compiled, 
++leading to unpredictable results, including crashes in JIT compiling. An 
++example pattern is: /(((?<=123?456456|ABC)))(?<=\2)/
++
+ Version 10.43 16-February-2024
+ ------------------------------
 diff --git a/src/pcre2_compile.c b/src/pcre2_compile.c
-index 8b364977..71c2dbca 100644
+index 95c97710..e66e40f6 100644
 --- a/src/pcre2_compile.c
 +++ b/src/pcre2_compile.c
-@@ -9908,7 +9908,7 @@ do
+@@ -9909,7 +9909,7 @@ do
    *bptr |= branchlength;  /* branchlength never more than 65535 */
    bptr = *pptrptr;
    }
@@ -59,6 +72,3 @@ index ee1f70b0..30c5a83e 100644
  # End of testinput2
  Error -70: PCRE2_ERROR_BADDATA (unknown error number)
  Error -62: bad serialized data
--- 
-2.51.2.vfs.0.0
-
index 39c1fb0d389cdc1ddd51987fbf2f425c64ceb87a..5e159ce04326e4297d51bd466667dbb639829332 100644 (file)
@@ -1,19 +1,17 @@
-From c0fdb5f7013ecc10292ed9e697b3fe901e38cd77 Mon Sep 17 00:00:00 2001
-From: lbonn <lbonn@users.noreply.github.com>
-Date: Tue, 2 Apr 2024 12:55:33 +0200
-Subject: [PATCH] Fix locking region in sjlit_malloc_exec
+commit c0fdb5f7013ecc10292ed9e697b3fe901e38cd77
+Author: lbonn <lbonn@users.noreply.github.com>
+Date:   Tue Apr 2 12:55:33 2024 +0200
 
-Cherry-picked from ad89dd8ecd25589d236bd20b36f2abf69f938fd1
-(https://github.com/zherczeg/sljit.git)
-
-The locked section needs to extend until we are done modifying internal
-block offsets and sizes, otherwise we risk running into data corruption
-in a multi-threaded context.
-
-This bug was introduced in 7de0fee9a7376b33e31a3903487cd9933da3a606
----
- src/sljit/allocator_src/sljitExecAllocatorCore.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
+    Fix locking region in sjlit_malloc_exec
+    
+    Cherry-picked from ad89dd8ecd25589d236bd20b36f2abf69f938fd1
+    (https://github.com/zherczeg/sljit.git)
+    
+    The locked section needs to extend until we are done modifying internal
+    block offsets and sizes, otherwise we risk running into data corruption
+    in a multi-threaded context.
+    
+    This bug was introduced in 7de0fee9a7376b33e31a3903487cd9933da3a606
 
 diff --git a/src/sljit/allocator_src/sljitExecAllocatorCore.c b/src/sljit/allocator_src/sljitExecAllocatorCore.c
 index 6cd39110..4ef39c17 100644
@@ -33,6 +31,3 @@ index 6cd39110..4ef39c17 100644
        return MEM_START(header);
  }
  
--- 
-2.51.2.vfs.0.0
-
index 93380882702f63ef3bec0347889be7b952359f4d..b6b9fc716ee8a4a99658b3c58dbfed442f02440e 100644 (file)
@@ -1,39 +1,23 @@
-From e669b61ecf6ae3af2a4f0c714c6723ccc073ecd5 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Carlo=20Marcelo=20Arenas=20Bel=C3=B3n?= <carenas@gmail.com>
-Date: Sun, 9 Jun 2024 08:22:15 -0700
-Subject: [PATCH] pcre2test: memory reports only compiled memory usage for
- code/data (#418)
+commit 57906628d7babd27c01eb1c085d3e0cdd512189a
+Author: Carlo Marcelo Arenas Belón <carenas@gmail.com>
+Date:   Sun Jun 9 08:22:15 2024 -0700
 
-Cherry-pick of 57906628d7babd27c01eb1c085d3e0cdd512189a.
-
-Since 05aafb2 (Implement pcre2_set_max_pattern_compiled_length() and set
-this limit in the fuzzer, 2024-04-24), the memory modifier has reported
-the full size of the allocated "code" returned by `pcre2_compile`.
-
-Problem is that the size of the structure used to hold that in memory also
-depends on the platform ABI and even alignment by the compiler, and has
-been therefore fragile to compare.
-
-Revert to reporting only the additional memory that `pcre2_compile()` will
-use for the compiled pattern (including any data tables) and make sure
-that the limit provided with `pcre2_set_max_pattern_compiled_length()`
-also avoid the internal struct overhead.
-
-Fixes: #415
----
- doc/pcre2_set_max_pattern_compiled_length.3 |   8 +-
- src/pcre2_compile.c                         |   4 +-
- src/pcre2test.c                             |  17 +-
- testdata/testoutput8-16-2                   | 171 +++++++-------------
- testdata/testoutput8-16-3                   | 171 +++++++-------------
- testdata/testoutput8-16-4                   | 171 +++++++-------------
- testdata/testoutput8-32-2                   | 171 +++++++-------------
- testdata/testoutput8-32-3                   | 171 +++++++-------------
- testdata/testoutput8-32-4                   | 171 +++++++-------------
- testdata/testoutput8-8-2                    | 171 +++++++-------------
- testdata/testoutput8-8-3                    | 171 +++++++-------------
- testdata/testoutput8-8-4                    | 171 +++++++-------------
- 12 files changed, 546 insertions(+), 1022 deletions(-)
+    pcre2test: memory reports only compiled memory usage for code/data (#418)
+    
+    Since 05aafb2 (Implement pcre2_set_max_pattern_compiled_length() and set
+    this limit in the fuzzer, 2024-04-24), the memory modifier has reported
+    the full size of the allocated "code" returned by `pcre2_compile`.
+    
+    Problem is that the size of the structure used to hold that in memory also
+    depends on the platform ABI and even alignment by the compiler, and has
+    been therefore fragile to compare.
+    
+    Revert to reporting only the additional memory that `pcre2_compile()` will
+    use for the compiled pattern (including any data tables) and make sure
+    that the limit provided with `pcre2_set_max_pattern_compiled_length()`
+    also avoid the internal struct overhead.
+    
+    Fixes: #415
 
 diff --git a/doc/pcre2_set_max_pattern_compiled_length.3 b/doc/pcre2_set_max_pattern_compiled_length.3
 index 472a7bbd..679c12c2 100644
@@ -5223,6 +5207,3 @@ index 81cf0f76..8bfac41a 100644
  ------------------------------------------------------------------
    0   8 Bra
    5     [^\x{aa}]
--- 
-2.51.2.vfs.0.0
-
index 7ec98fe4329b91c3f3ef4138d5b260e5d4325c96..c1e81ae6f6a3e19a745437335a20f3fc3dea1fdc 100644 (file)
@@ -1,36 +1,28 @@
-From 39c3fd67ef9ca22c39f128bf476e238b0e886975 Mon Sep 17 00:00:00 2001
-From: Nicholas Wilson <nicholas@nicholaswilson.me.uk>
-Date: Fri, 26 Sep 2025 11:37:10 +0100
-Subject: [PATCH] Add fix and tests for callback enumerate (#801)
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
+commit cc6c84d0207d9d09ca9e42996f0bc50353c03157
+Author: Nicholas Wilson <nicholas@nicholaswilson.me.uk>
+Date:   Fri Sep 26 11:37:10 2025 +0100
 
-Cherry-pick of commit cc6c84d0207d9d09ca9e42996f0bc50353c03157.
-
-This is a bug in PCRE2 10.45 and 10.46, not present in 10.44 and earlier.
-
-The bug is that applications using pcre2_callout_enumerate() will crash badly on patterns with Unicode (ie non-ASCII) character classes. There is an out-of-bounds read of arbitrary length, including misinterpreting the bytes as offsets, allowing the read to jump forwards in memory to pretty much anywhere.
-
-Applications which call pcre2_callout_enumerate should potentially downgrade to PCRE2 10.44 until we release an update of PCRE2 with the fix.
-
-Since this function is (clearly!!) not used often by applications, I am not currently treating this as very high severity. There is no way for an attacker to make any application call this function, if it is not currently using it.
-
-The root cause seems to be commit 24f9d8d (#540).
-
----------
-
-Co-authored-by: Carlo Marcelo Arenas Belón <carenas@gmail.com>
----
- src/pcre2_pattern_info.c |  3 +-
- src/pcre2test.c          | 61 ++++++++++++++++++++++------------------
- 2 files changed, 34 insertions(+), 30 deletions(-)
+    Add fix and tests for callback enumerate (#801)
+    
+    This is a bug in PCRE2 10.45 and 10.46, not present in 10.44 and earlier.
+    
+    The bug is that applications using pcre2_callout_enumerate() will crash badly on patterns with Unicode (ie non-ASCII) character classes. There is an out-of-bounds read of arbitrary length, including misinterpreting the bytes as offsets, allowing the read to jump forwards in memory to pretty much anywhere.
+    
+    Applications which call pcre2_callout_enumerate should potentially downgrade to PCRE2 10.44 until we release an update of PCRE2 with the fix.
+    
+    Since this function is (clearly!!) not used often by applications, I am not currently treating this as very high severity. There is no way for an attacker to make any application call this function, if it is not currently using it.
+    
+    The root cause seems to be commit 24f9d8d (#540).
+    
+    ---------
+    
+    Co-authored-by: Carlo Marcelo Arenas Belón <carenas@gmail.com>
 
 diff --git a/src/pcre2_pattern_info.c b/src/pcre2_pattern_info.c
-index fe4d3c66..c49eaf69 100644
+index d8786318..e0bd83a9 100644
 --- a/src/pcre2_pattern_info.c
 +++ b/src/pcre2_pattern_info.c
-@@ -292,8 +292,7 @@ if (re->magic_number != MAGIC_NUMBER) return PCRE2_ERROR_BADMAGIC;
+@@ -289,8 +289,7 @@ if (re->magic_number != MAGIC_NUMBER) return PCRE2_ERROR_BADMAGIC;
  if ((re->flags & (PCRE2_CODE_UNIT_WIDTH/8)) == 0) return PCRE2_ERROR_BADMODE;
  
  cb.version = 0;
@@ -41,10 +33,10 @@ index fe4d3c66..c49eaf69 100644
  while (TRUE)
    {
 diff --git a/src/pcre2test.c b/src/pcre2test.c
-index 80ab4f80..6ac638ce 100644
+index b2620f59..dbb1cb56 100644
 --- a/src/pcre2test.c
 +++ b/src/pcre2test.c
-@@ -512,7 +512,6 @@ so many of them that they are split into two fields. */
+@@ -558,7 +558,6 @@ so many of them that they are split into two fields. */
  /* Combinations */
  
  #define CTL_DEBUG            (CTL_FULLBINCODE|CTL_INFO)  /* For setting */
@@ -52,30 +44,17 @@ index 80ab4f80..6ac638ce 100644
  #define CTL_ANYGLOB          (CTL_ALTGLOBAL|CTL_GLOBAL)
  
  /* Second control word */
-@@ -4652,6 +4651,16 @@ fprintf(outfile, "%.*s\n",
- return 0;
- }
-+/* Backport from 10.47 */
-+
-+static int callout_enumerate_function_void(pcre2_callout_enumerate_block_8 *cb,
-+  void *callout_data)
-+{
-+(void)cb;
-+(void)callout_data;
-+return 0;
-+}
-+
- /*************************************************
-@@ -4671,9 +4680,16 @@ Returns:    PR_OK     continue processing next line
+diff --git a/src/pcre2test_inc.h b/src/pcre2test_inc.h
+index 28673ebb..5b5f6424 100644
+--- a/src/pcre2test_inc.h
++++ b/src/pcre2test_inc.h
+@@ -1258,9 +1258,16 @@ Returns:    PR_OK     continue processing next line
  static int
  show_pattern_info(void)
  {
 +int rc;
  uint32_t compile_options, overall_options, extra_options;
- BOOL utf = (FLD(compiled_code, overall_options) & PCRE2_UTF) != 0;
+ BOOL utf = (compiled_code->overall_options & PCRE2_UTF) != 0;
  
 +if ((pat_patctl.control & CTL_MEMORY) != 0)
 +  show_memory_info();
@@ -86,20 +65,20 @@ index 80ab4f80..6ac638ce 100644
  if ((pat_patctl.control & (CTL_BINCODE|CTL_FULLBINCODE)) != 0)
    {
    fprintf(outfile, "------------------------------------------------------------------\n");
-@@ -5016,17 +5032,17 @@ if ((pat_patctl.control & CTL_INFO) != 0)
+@@ -1586,17 +1593,17 @@ if ((pat_patctl.control & CTL_INFO) != 0)
      }
    }
  
 -if ((pat_patctl.control & CTL_CALLOUT_INFO) != 0)
-+PCRE2_CALLOUT_ENUMERATE(rc,
-+  (((pat_patctl.control & CTL_CALLOUT_INFO) != 0)? callout_callback :
++rc = pcre2_callout_enumerate(compiled_code,
++  ((pat_patctl.control & CTL_CALLOUT_INFO) != 0)? callout_enumerate_function :
 +  /* Exercise the callout enumeration code with a dummy callback to make sure
 +  it works. */
-+  callout_enumerate_function_void), 0);
++  callout_enumerate_function_void, NULL);
 +if (rc != 0)
    {
--  int errorcode;
--  PCRE2_CALLOUT_ENUMERATE(errorcode, callout_callback, 0);
+-  int errorcode = pcre2_callout_enumerate(compiled_code,
+-    callout_enumerate_function, NULL);
 -  if (errorcode != 0)
 -    {
 -    fprintf(outfile, "Callout enumerate failed: error %d: ", errorcode);
@@ -114,9 +93,9 @@ index 80ab4f80..6ac638ce 100644
    }
  
  return PR_OK;
-@@ -5230,13 +5246,9 @@ switch(cmd)
+@@ -1763,13 +1770,9 @@ switch(cmd)
      {
-     PCRE2_JIT_COMPILE(jitrc, compiled_code, pat_patctl.jit);
+     jitrc = pcre2_jit_compile(compiled_code, pat_patctl.jit);
      }
 -  if ((pat_patctl.control & CTL_MEMORY) != 0) show_memory_info();
 -  if ((pat_patctl.control2 & CTL2_FRAMESIZE) != 0) show_framesize();
@@ -131,32 +110,32 @@ index 80ab4f80..6ac638ce 100644
    break;
  
    /* Save the stack of compiled patterns to a file, then empty the stack. */
-@@ -5395,7 +5407,7 @@ BOOL utf;
+@@ -1979,7 +1982,7 @@ BOOL utf;
  uint32_t k;
  uint8_t *p = buffer;
  unsigned int delimiter = *p++;
 -int errorcode;
 +int rc, errorcode;
void *use_pat_context;
void *use_pbuffer = NULL;
pcre2_compile_context *use_pat_context;
PCRE2_SPTR use_pbuffer = NULL;
  uint32_t use_forbid_utf = forbid_utf;
-@@ -5724,7 +5736,6 @@ local character tables. Neither does it have 16-bit or 32-bit support. */
- if ((pat_patctl.control & CTL_POSIX) != 0)
-   {
- #ifdef SUPPORT_PCRE2_8
+@@ -2313,7 +2316,6 @@ if ((pat_patctl.control & CTL_POSIX) != 0)
+   return PR_SKIP;
+ #else
 -  int rc;
    int cflags = 0;
    const char *msg = "** Ignored with POSIX interface:";
- #endif
-@@ -5931,7 +5942,6 @@ ends up back in the usual place. */
+@@ -2523,7 +2525,6 @@ ends up back in the usual place. */
  
  if (pat_patctl.convert_type != CONVERT_UNSET)
    {
 -  int rc;
    int convert_return = PR_OK;
    uint32_t convert_options = pat_patctl.convert_type;
-   void *converted_pattern;
-@@ -6246,13 +6256,8 @@ if ((pat_patctl.control2 & CTL2_NL_SET) != 0)
+   PCRE2_UCHAR *converted_pattern;
+@@ -2918,13 +2919,8 @@ if ((pat_patctl.control2 & CTL2_NL_SET) != 0)
  
  /* Output code size and other information if requested. */
  
@@ -172,6 +151,3 @@ index 80ab4f80..6ac638ce 100644
  
  /* The "push" control requests that the compiled pattern be remembered on a
  stack. This is mainly for testing the serialization functionality. */
--- 
-2.51.2.vfs.0.0
-
diff --git a/patches/pcre2-10.48-Check-JIT-mode-before-validation.patch b/patches/pcre2-10.48-Check-JIT-mode-before-validation.patch
new file mode 100644 (file)
index 0000000..7bf7eb2
--- /dev/null
@@ -0,0 +1,382 @@
+commit f67db227af31bba7cdf2a7a00b97af91b588c2f5
+Author: Zoltan Herczeg <zherczeg7@gmail.com>
+Date:   Sun Aug 9 11:05:54 2026 +0200
+
+    Fix pcre2_match to check for JIT support before JIT validation & execution (#926)
+    
+    This fixes the issue that the JIT branch's UTF validation is not pinned to be identical to the interpreter's validation.
+    
+    This was not robust, and lead to a bug, in the case where the JIT UTF validation is done, but because the relevant JIT mode was not compiled, it falls through to the interpreter and skips the interpreter's own UTF validation and setup.
+
+diff --git a/src/pcre2_internal.h b/src/pcre2_internal.h
+index 2e8c7e47..930c745b 100644
+--- a/src/pcre2_internal.h
++++ b/src/pcre2_internal.h
+@@ -2301,6 +2301,7 @@ is available. */
+ #define _pcre2_is_newline            PCRE2_SUFFIX(_pcre2_is_newline_)
+ #define _pcre2_jit_free_rodata       PCRE2_SUFFIX(_pcre2_jit_free_rodata_)
+ #define _pcre2_jit_free              PCRE2_SUFFIX(_pcre2_jit_free_)
++#define _pcre2_jit_check_exec        PCRE2_SUFFIX(_pcre2_jit_check_exec_)
+ #define _pcre2_jit_get_size          PCRE2_SUFFIX(_pcre2_jit_get_size_)
+ #define _pcre2_jit_get_target        PCRE2_SUFFIX(_pcre2_jit_get_target_)
+ #define _pcre2_memctl_malloc         PCRE2_SUFFIX(_pcre2_memctl_malloc_)
+@@ -2330,6 +2331,7 @@ extern BOOL         _pcre2_is_newline(PCRE2_SPTR, uint32_t, PCRE2_SPTR,
+                       uint32_t *, BOOL);
+ extern void         _pcre2_jit_free_rodata(void *, void *);
+ extern void         _pcre2_jit_free(void *, pcre2_memctl *);
++extern BOOL         _pcre2_jit_check_exec(void *, uint32_t);
+ extern size_t       _pcre2_jit_get_size(void *);
+ const char *        _pcre2_jit_get_target(void);
+ extern void *       _pcre2_memctl_malloc(size_t, pcre2_memctl *);
+diff --git a/src/pcre2_jit_match_inc.h b/src/pcre2_jit_match_inc.h
+index 4163cf61..ba210007 100644
+--- a/src/pcre2_jit_match_inc.h
++++ b/src/pcre2_jit_match_inc.h
+@@ -117,6 +117,7 @@ jit_arguments arguments;
+ int rc;
+ int index = 0;
++/* The same check is performed by jit_check_exec(). */
+ if ((options & PCRE2_PARTIAL_HARD) != 0)
+   index = 2;
+ else if ((options & PCRE2_PARTIAL_SOFT) != 0)
+diff --git a/src/pcre2_jit_misc_inc.h b/src/pcre2_jit_misc_inc.h
+index 0225fc6b..16c230e9 100644
+--- a/src/pcre2_jit_misc_inc.h
++++ b/src/pcre2_jit_misc_inc.h
+@@ -200,17 +200,28 @@ if (jit_stack != NULL)
+ /*************************************************
+-*               Get target CPU type              *
++*          Checks function compilation           *
+ *************************************************/
+-const char*
+-PRIV(jit_get_target)(void)
++BOOL
++PRIV(jit_check_exec)(void *executable_jit, uint32_t options)
+ {
+ #ifndef SUPPORT_JIT
+-return "JIT is not supported";
++(void)executable_jit;
++(void)options;
++return FALSE;
+ #else  /* SUPPORT_JIT */
+-return sljit_get_platform_name();
+-#endif  /* SUPPORT_JIT */
++/* The same check is performed at the beginning of pcre2_jit_match(). */
++executable_functions *functions = (executable_functions *)executable_jit;
++int index = 0;
++
++if ((options & PCRE2_PARTIAL_HARD) != 0)
++  index = 2;
++else if ((options & PCRE2_PARTIAL_SOFT) != 0)
++  index = 1;
++
++return functions->executable_funcs[index] != NULL;
++#endif
+ }
+@@ -231,4 +242,19 @@ return executable_sizes[0] + executable_sizes[1] + executable_sizes[2];
+ #endif
+ }
++/*************************************************
++*               Get target CPU type              *
++*************************************************/
++
++const char*
++PRIV(jit_get_target)(void)
++{
++#ifndef SUPPORT_JIT
++return "JIT is not supported";
++#else  /* SUPPORT_JIT */
++return sljit_get_platform_name();
++#endif  /* SUPPORT_JIT */
++}
++
++
+ /* End of pcre2_jit_misc_inc.h */
+diff --git a/src/pcre2_match.c b/src/pcre2_match.c
+index 9ee8a476..a5a8421f 100644
+--- a/src/pcre2_match.c
++++ b/src/pcre2_match.c
+@@ -7005,10 +7005,6 @@ PCRE2_SPTR req_cu_ptr;
+ PCRE2_SPTR start_partial;
+ PCRE2_SPTR match_partial;
+-#ifdef SUPPORT_JIT
+-BOOL use_jit;
+-#endif
+-
+ /* This flag is needed even when Unicode is not supported for convenience
+ (it is used by the IS_NEWLINE macro). */
+@@ -7018,9 +7014,6 @@ BOOL utf = FALSE;
+ BOOL ucp = FALSE;
+ BOOL allow_invalid;
+ uint32_t fragment_options = 0;
+-#ifdef SUPPORT_JIT
+-BOOL jit_checked_utf = FALSE;
+-#endif
+ #endif  /* SUPPORT_UNICODE */
+ PCRE2_SIZE frame_size;
+@@ -7083,15 +7076,6 @@ options |= (re->flags & FF) / ((FF & (~FF+1)) / (OO & (~OO+1)));
+ #undef FF
+ #undef OO
+-/* If the pattern was successfully studied with JIT support, we will run the
+-JIT executable instead of the rest of this function. Most options must be set
+-at compile time for the JIT code to be usable. */
+-
+-#ifdef SUPPORT_JIT
+-use_jit = (re->executable_jit != NULL &&
+-          (options & ~PUBLIC_JIT_MATCH_OPTIONS) == 0);
+-#endif
+-
+ /* Initialize UTF/UCP parameters. */
+ #ifdef SUPPORT_UNICODE
+@@ -7138,20 +7122,25 @@ match_data->startchar = 0;
+ /* ============================= JIT matching ============================== */
+-/* Prepare for JIT matching. Check a UTF string for validity unless no check is
+-requested or invalid UTF can be handled. We check only the portion of the
+-subject that might be be inspected during matching - from the offset minus the
+-maximum lookbehind to the given length. This saves time when a small part of a
+-large subject is being matched by the use of a starting offset. Note that the
+-maximum lookbehind is a number of characters, not code units. */
++/* If the pattern was successfully studied with JIT support, we will run the
++JIT executable instead of the rest of this function. Most options must be set
++at compile time for the JIT code to be usable. */
+ #ifdef SUPPORT_JIT
+-if (use_jit)
++if (re->executable_jit != NULL &&
++    (options & ~PUBLIC_JIT_MATCH_OPTIONS) == 0 &&
++    PRIV(jit_check_exec)(re->executable_jit, options))
+   {
++  /* Prepare for JIT matching. Check a UTF string for validity unless no check
++  is requested or invalid UTF can be handled. We check only the portion of the
++  subject that might be be inspected during matching - from the offset minus
++  the maximum lookbehind to the given length. This saves time when a small part
++  of a large subject is being matched by the use of a starting offset. Note that
++  the maximum lookbehind is a number of characters, not code units. */
++
+ #ifdef SUPPORT_UNICODE
+   if (utf && (options & PCRE2_NO_UTF_CHECK) == 0 && !allow_invalid)
+     {
+-
+     /* For 8-bit and 16-bit UTF, check that the first code unit is a valid
+     character start. */
+@@ -7204,40 +7193,36 @@ if (use_jit)
+       match_data->startchar += start_match - subject;
+       return match_data->rc = rc;
+       }
+-    jit_checked_utf = TRUE;
+     }
+ #endif  /* SUPPORT_UNICODE */
+-  /* If JIT returns BADOPTION, which means that the selected complete or
+-  partial matching mode was not compiled, fall through to the interpreter. */
+-
+   rc = pcre2_jit_match(code, subject, length, start_offset, options,
+     match_data, mcontext);
+-  if (rc != PCRE2_ERROR_JIT_BADOPTION)
++  /* JIT must be able to perform the match. */
++  PCRE2_ASSERT(rc != PCRE2_ERROR_JIT_BADOPTION);
++
++  match_data->options = original_options;
++  if (rc >= 0 && (options & PCRE2_COPY_MATCHED_SUBJECT) != 0)
+     {
+-    match_data->options = original_options;
+-    if (rc >= 0 && (options & PCRE2_COPY_MATCHED_SUBJECT) != 0)
++    if (length != 0)
+       {
+-      if (length != 0)
+-        {
+-        match_data->subject = match_data->memctl.malloc(CU2BYTES(length),
+-          match_data->memctl.memory_data);
+-        if (match_data->subject == NULL)
+-          return match_data->rc = PCRE2_ERROR_NOMEMORY;
+-        memcpy((void *)match_data->subject, subject, CU2BYTES(length));
+-        }
+-      else
+-        match_data->subject = NULL;
+-      match_data->flags |= PCRE2_MD_COPIED_SUBJECT;
++      match_data->subject = match_data->memctl.malloc(CU2BYTES(length),
++        match_data->memctl.memory_data);
++      if (match_data->subject == NULL)
++        return match_data->rc = PCRE2_ERROR_NOMEMORY;
++      memcpy((void *)match_data->subject, subject, CU2BYTES(length));
+       }
+     else
+-      {
+-      /* When pcre2_jit_match sets the subject, it doesn't know what the
+-      original passed-in pointer was. */
+-      if (match_data->subject != NULL) match_data->subject = original_subject;
+-      }
+-    return rc;
++      match_data->subject = NULL;
++    match_data->flags |= PCRE2_MD_COPIED_SUBJECT;
+     }
++  else
++    {
++    /* When pcre2_jit_match sets the subject, it doesn't know what the
++    original passed-in pointer was. */
++    if (match_data->subject != NULL) match_data->subject = original_subject;
++    }
++  return rc;
+   }
+ #endif  /* SUPPORT_JIT */
+@@ -7250,12 +7235,8 @@ this. */
+ mb->check_subject = subject;
+-/* If a UTF subject string was not checked for validity in the JIT code above,
+-check it here, and handle support for invalid UTF strings. The check above
+-happens only when invalid UTF is not supported and PCRE2_NO_CHECK_UTF is unset.
+-If we get here in those circumstances, it means the subject string is valid,
+-but for some reason JIT matching was not successful. There is no need to check
+-the subject again.
++/* Check the validity of UTF subject strings. The check happens only when
++PCRE2_NO_CHECK_UTF is unset.
+ We check only the portion of the subject that might be be inspected during
+ matching - from the offset minus the maximum lookbehind to the given length.
+@@ -7267,11 +7248,7 @@ Note also that support for invalid UTF forces a check, overriding the setting
+ of PCRE2_NO_CHECK_UTF. */
+ #ifdef SUPPORT_UNICODE
+-if (utf &&
+-#ifdef SUPPORT_JIT
+-    !jit_checked_utf &&
+-#endif
+-    ((options & PCRE2_NO_UTF_CHECK) == 0 || allow_invalid))
++if (utf && ((options & PCRE2_NO_UTF_CHECK) == 0 || allow_invalid))
+   {
+ #if PCRE2_CODE_UNIT_WIDTH != 32
+   BOOL skipped_bad_start = FALSE;
+
+commit e2f100156b94cf85dce9046b47a3274590487de4
+Author: Nicholas Wilson <nicholas@nicholaswilson.me.uk>
+Date:   Wed Aug 12 10:18:54 2026 +0100
+
+    Add a testcase for #926 (#940)
+
+diff --git a/RunTest b/RunTest
+index 57a03455..306427b6 100755
+--- a/RunTest
++++ b/RunTest
+@@ -175,9 +175,12 @@ checkresult()
+     *)    with="";;
+   esac
+   cf_out="$testdata/testoutput$2"
+-  if [ $ebcdic -eq 1 ] ; then
+-    # We currently only use the #if ... #endif support in pcre2test for EBCDIC
+-    # testing. Run in "preprocess-only" mode (-E) on the testoutput file to trim
++  if [ $ebcdic -eq 1 ] || [ $utf -eq 0 ]; then
++    # We currently only use the #if ... #endif support in pcre2test for tests
++    # which are excluded in certain builds:
++    #   - EBCDIC
++    #   - No-UTF
++    # Run in "preprocess-only" mode (-E) on the testoutput file to trim
+     # the output lines matching the input lines which are discarded.
+     $sim $pcre2test -q -E "$cf_out" >testoutput$bits$3/testoutput$2-expected
+     cf_out=testoutput$bits$3/testoutput$2-expected
+diff --git a/src/pcre2test_inc.h b/src/pcre2test_inc.h
+index a74e3368..72767916 100644
+--- a/src/pcre2test_inc.h
++++ b/src/pcre2test_inc.h
+@@ -1712,7 +1712,7 @@ process_command(void)
+ FILE *f;
+ PCRE2_SIZE serial_size;
+ size_t i;
+-int rc, cmd, yield;
++int rc, cmd, yield, config_value;
+ uint16_t first_listed_newline;
+ const char *cmdname;
+ size_t cmdlen;
+@@ -1980,7 +1980,7 @@ switch(cmd)
+     {
+     size_t optlen = strlen(coptlist[i].name);
+     const uint8_t *argptr_trail;
+-    if (coptlist[i].type != CONF_FIX)
++    if (coptlist[i].type != CONF_FIX && coptlist[i].type != CONF_INT)
+       continue;
+     if (strncmp((const char*)argptr, coptlist[i].name, optlen) != 0)
+       continue;
+@@ -1995,9 +1995,20 @@ switch(cmd)
+     return PR_ABEND;
+     }
+-  /* Condition FALSE - skip this line and everything until #endif. */
+-  if ((coptlist[i].value != 0) == if_inverted)
++  if (coptlist[i].type == CONF_FIX)
++    {
++    config_value = coptlist[i].value;
++    }
++  else /* if (coptlist[i].type == CONF_INT) */
++    {
++    (void)pcre2_config(coptlist[i].value, &config_value);
++    }
++
++  if ((config_value != 0) == if_inverted)
++    {
++    /* Condition FALSE - skip this line and everything until #endif. */
+     yield = PR_ENDIF;
++    }
+   inside_if = TRUE;
+   break;
+diff --git a/testdata/testinput17 b/testdata/testinput17
+index 9d728965..e6dbbe42 100644
+--- a/testdata/testinput17
++++ b/testdata/testinput17
+@@ -336,4 +336,14 @@
+     zabcz\=callout_error=1
+     zabcz\=callout_error=1,substitute_matched
++# Check UTF validation when falling back from a partially-compiled JIT pattern
++# to the interpreter
++
++#if unicode
++
++/\b/B,utf,ucp,jit=1
++    \xff\x00\x00\=offset=2,ps
++
++#endif
++
+ # End of testinput17
+diff --git a/testdata/testoutput17 b/testdata/testoutput17
+index 773ec18a..11f032d8 100644
+--- a/testdata/testoutput17
++++ b/testdata/testoutput17
+@@ -603,4 +603,21 @@ Failed: error -37: callout error code
+   1  ^        a
+ Failed: error -37: callout error code
++# Check UTF validation when falling back from a partially-compiled JIT pattern
++# to the interpreter
++
++#if unicode
++
++/\b/B,utf,ucp,jit=1
++------------------------------------------------------------------
++        Bra
++        \b (ucp)
++        Ket
++        End
++------------------------------------------------------------------
++    \xff\x00\x00\=offset=2,ps
++Partial match: 
++
++#endif
++
+ # End of testinput17
diff --git a/patches/pcre2-10.48-Fix-DFA-workspace-overflows.patch b/patches/pcre2-10.48-Fix-DFA-workspace-overflows.patch
new file mode 100644 (file)
index 0000000..81fb1b5
--- /dev/null
@@ -0,0 +1,149 @@
+commit c932e70451eafef922ebef364ac25042f0031135
+Author: Nicholas Wilson <nicholas@nicholaswilson.me.uk>
+Date:   Thu Aug 27 16:52:16 2026 +0100
+
+    Fix DFA workspace overflows; see GHSA-3r4p-g7gg-ppmf for details
+
+diff --git a/src/pcre2_dfa_match.c b/src/pcre2_dfa_match.c
+index 314e9775..8e9512c4 100644
+--- a/src/pcre2_dfa_match.c
++++ b/src/pcre2_dfa_match.c
+@@ -405,8 +405,8 @@ return (mb->callout)(cb, mb->callout_data);
+ /* This function is called when internal_dfa_match() is about to be called
+ recursively and there is insufficient working space left in the current
+-workspace block. If there's an existing next block, use it; otherwise get a new
+-block unless the heap limit is reached.
++workspace block. If there's a sufficiently large next block, use it; get a new
++block unless the heap limit is (or has been) reached.
+ Arguments:
+   rwsptr     pointer to block pointer (updated)
+@@ -422,9 +422,18 @@ more_workspace(RWS_anchor **rwsptr, unsigned int ovecsize, dfa_match_block *mb)
+ {
+ RWS_anchor *rws = *rwsptr;
+ RWS_anchor *new;
++uint32_t requested;
++
++PCRE2_ASSERT(ovecsize <= UINT32_MAX - RWS_RSIZE - RWS_ANCHOR_SIZE);
++requested = RWS_RSIZE + ovecsize + RWS_ANCHOR_SIZE;
+ if (rws->next != NULL)
+   {
++  /* Although the initial block is large, and subsequent ones try to double, the
++  heap limit may cause the last one to be smaller; in this case, we have already
++  hit the heap limit and allocating a larger block will not be possible. */
++  if (rws->next->size < requested)
++    return PCRE2_ERROR_HEAPLIMIT;
+   new = rws->next;
+   }
+@@ -434,14 +443,30 @@ overflow. */
+ else
+   {
+-  uint32_t newsize = (rws->size >= UINT32_MAX/(sizeof(int)*2))? UINT32_MAX/sizeof(int) : rws->size * 2;
++  uint32_t newsize = (rws->size >= (UINT32_MAX/sizeof(int))/2)?
++    UINT32_MAX/sizeof(int) : rws->size * 2;
+   uint32_t newsizeK = newsize/(1024/sizeof(int));
+-  if (newsizeK + mb->heap_used > mb->heap_limit)
+-    newsizeK = (uint32_t)(mb->heap_limit - mb->heap_used);
+-  newsize = newsizeK*(1024/sizeof(int));
++  /* Clamp the allocation to the remaining heap allowance with care for overflows */
++
++  if (mb->heap_used >= mb->heap_limit)
++    {
++    newsize = 0;
++    newsizeK = 0;
++    }
++  else
++    {
++    PCRE2_SIZE availableK = mb->heap_limit - mb->heap_used;
++    /* newsize always capped at UINT32_MAX/sizeof(int), so newsizeK also capped;
++    and - if availableK is smaller - then multiplication to form newsize is safe */
++    if (newsizeK > availableK)
++      {
++      newsize = (uint32_t)(availableK*(1024/sizeof(int)));
++      newsizeK = availableK;
++      }
++    }
+-  if (newsize < RWS_RSIZE + ovecsize + RWS_ANCHOR_SIZE)
++  if (newsize < requested)
+     return PCRE2_ERROR_HEAPLIMIT;
+   new = mb->memctl.malloc(newsize*sizeof(int), mb->memctl.memory_data);
+   if (new == NULL) return PCRE2_ERROR_NOMEMORY;
+@@ -2801,6 +2826,7 @@ for (;;)
+         local_offsets = (PCRE2_SIZE *)(RWS + rws->size - rws->free);
+         local_workspace = ((int *)local_offsets) + RWS_OVEC_OSIZE;
++        PCRE2_ASSERT(rws->free >= RWS_RSIZE + RWS_OVEC_OSIZE);
+         rws->free -= RWS_RSIZE + RWS_OVEC_OSIZE;
+         while (*endasscode == OP_ALT) endasscode += GET(endasscode, 1);
+@@ -2900,6 +2926,7 @@ for (;;)
+           local_offsets = (PCRE2_SIZE *)(RWS + rws->size - rws->free);
+           local_workspace = ((int *)local_offsets) + RWS_OVEC_OSIZE;
++          PCRE2_ASSERT(rws->free >= RWS_RSIZE + RWS_OVEC_OSIZE);
+           rws->free -= RWS_RSIZE + RWS_OVEC_OSIZE;
+           while (*endasscode == OP_ALT) endasscode += GET(endasscode, 1);
+@@ -2951,6 +2978,7 @@ for (;;)
+         local_offsets = (PCRE2_SIZE *)(RWS + rws->size - rws->free);
+         local_workspace = ((int *)local_offsets) + RWS_OVEC_RSIZE;
++        PCRE2_ASSERT(rws->free >= RWS_RSIZE + RWS_OVEC_RSIZE);
+         rws->free -= RWS_RSIZE + RWS_OVEC_RSIZE;
+         /* Check for repeating a recursion without advancing the subject
+@@ -3050,6 +3078,7 @@ for (;;)
+         local_offsets = (PCRE2_SIZE *)(RWS + rws->size - rws->free);
+         local_workspace = ((int *)local_offsets) + RWS_OVEC_OSIZE;
++        PCRE2_ASSERT(rws->free >= RWS_RSIZE + RWS_OVEC_OSIZE);
+         rws->free -= RWS_RSIZE + RWS_OVEC_OSIZE;
+         if (codevalue == OP_BRAPOSZERO)
+@@ -3149,6 +3178,7 @@ for (;;)
+         local_offsets = (PCRE2_SIZE *)(RWS + rws->size - rws->free);
+         local_workspace = ((int *)local_offsets) + RWS_OVEC_OSIZE;
++        PCRE2_ASSERT(rws->free >= RWS_RSIZE + RWS_OVEC_OSIZE);
+         rws->free -= RWS_RSIZE + RWS_OVEC_OSIZE;
+         rc = internal_dfa_match(
+diff --git a/testdata/testinput6 b/testdata/testinput6
+index f6f5cbf4..197f6f76 100644
+--- a/testdata/testinput6
++++ b/testdata/testinput6
+@@ -5263,4 +5263,11 @@
+     abc\=replace=xyz
+     abc\=replace=xyz,substitute_matched
++# --------------
++
++# Test workspace resizing and workspace re-use
++
++/(*LIMIT_HEAP=4)(?=(?=(?=(?=(?=(?=(?=(?=a))(?R)))))))./
++    a\=dfa
++
+ # End of testinput6
+diff --git a/testdata/testoutput6 b/testdata/testoutput6
+index 8ecf0040..4316c8a6 100644
+--- a/testdata/testoutput6
++++ b/testdata/testoutput6
+@@ -8237,4 +8237,12 @@ Failed: error -42: pattern contains an item that is not supported for DFA matchi
+     abc\=replace=xyz,substitute_matched
+ Failed: error -41: function is not supported for DFA matching
++# --------------
++
++# Test workspace resizing and workspace re-use
++
++/(*LIMIT_HEAP=4)(?=(?=(?=(?=(?=(?=(?=(?=a))(?R)))))))./
++    a\=dfa
++Failed: error -63: heap limit exceeded
++
+ # End of testinput6
diff --git a/patches/pcre2-10.48-Fix-JIT-STR_END.patch b/patches/pcre2-10.48-Fix-JIT-STR_END.patch
new file mode 100644 (file)
index 0000000..3761004
--- /dev/null
@@ -0,0 +1,34 @@
+commit ff92e0b9cea5b5ae3af12ba930d03556684f098b
+Author: Zoltan Herczeg <zherczeg7@gmail.com>
+Date:   Thu May 21 05:56:00 2026 +0200
+
+    Fix setting STR_END in JIT (#912)
+    
+    When OP_VREVERSE is present in a non-atomic LOOKBEHIND ASSERTION,
+    the STR_END must be set before the backtracking path is executed.
+
+diff --git a/src/pcre2_jit_compile.c b/src/pcre2_jit_compile.c
+index 5d8c1c14..9013b686 100644
+--- a/src/pcre2_jit_compile.c
++++ b/src/pcre2_jit_compile.c
+@@ -12520,6 +12520,8 @@ else if (SLJIT_UNLIKELY(opcode == OP_ASSERT_SCS))
+   if (common->restore_end_ptr == 0)
+     common->restore_end_ptr = private_data_ptr + sizeof(sljit_sw);
+   }
++else if (SLJIT_UNLIKELY(opcode == OP_ASSERTBACK_NA) && PRIVATE_DATA(ccbegin + 1))
++  OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
+ if (SLJIT_UNLIKELY(opcode == OP_ONCE))
+   {
+diff --git a/src/pcre2_jit_test.c b/src/pcre2_jit_test.c
+index 03cc348b..7c4bcd68 100644
+--- a/src/pcre2_jit_test.c
++++ b/src/pcre2_jit_test.c
+@@ -657,6 +657,7 @@ static struct regression_test_case regression_test_cases[] = {
+       { MU, A, 0, 0 | F_NOMATCH, "a(?!)b", "ab" },
+       { MU, A, 0, 0, "(?(?<!|(|a)))", "a" },
+       { MU, A, 0, 0, "(?=((?|(a)(.)|(b)(..)|(c)(...)))(?1(2,3))).x", "b12c123bx2c123" },
++      { MU, A, 0, 3, "(?<*(.).{,2})\\1", "BABA" },
+       /* Not empty, ACCEPT, FAIL */
+       { MU, A, PCRE2_NOTEMPTY, 0 | F_NOMATCH, "a*", "bcx" },
diff --git a/patches/pcre2-10.48-Fix-JIT-match-context-reuse.patch b/patches/pcre2-10.48-Fix-JIT-match-context-reuse.patch
new file mode 100644 (file)
index 0000000..df824d3
--- /dev/null
@@ -0,0 +1,480 @@
+commit 1dcd0cf42a6a7cb62cc9a7c024196733abcfda95
+Author: Nicholas Wilson <nicholas@nicholaswilson.me.uk>
+Date:   Sat Aug 8 19:17:36 2026 +0100
+
+    Fix leak & stale PCRE2_MD_COPIED_SUBJECT if pcre2_jit_match used with existing match context (#937)
+    
+    The problem is not that pcre2_jit_match() needs to add support for PCRE2_COPY_MATCHED_SUBJECT. Instead, if the passed-in context somehow contains a previously-copied subject (by non-JIT matcher using a global or cached subject) then it will be leaked, and worse, incorrectly free'd later.
+
+diff --git a/doc/html/pcre2jit.html b/doc/html/pcre2jit.html
+index cc26cc06..4e6d31e5 100644
+--- a/doc/html/pcre2jit.html
++++ b/doc/html/pcre2jit.html
+@@ -460,10 +460,11 @@ processed by <b>pcre2_jit_compile()</b>).
+ The fast path function is called <b>pcre2_jit_match()</b>, and it takes exactly
+ the same arguments as <b>pcre2_match()</b>. However, the subject string must be
+ specified with a length; PCRE2_ZERO_TERMINATED is not supported. Unsupported
+-option bits (for example, PCRE2_ANCHORED and PCRE2_ENDANCHORED) are ignored, as
+-is the PCRE2_NO_JIT option. The return values are also the same as for
+-<b>pcre2_match()</b>, plus PCRE2_ERROR_JIT_BADOPTION if a matching mode (partial
+-or complete) is requested that was not compiled.
++option bits (for example, PCRE2_ANCHORED, PCRE2_ENDANCHORED, and
++PCRE2_COPY_MATCHED_SUBJECT) are ignored, as is the PCRE2_NO_JIT option. The
++return values are also the same as for <b>pcre2_match()</b>, plus
++PCRE2_ERROR_JIT_BADOPTION if a matching mode (partial or complete) is requested
++that was not compiled.
+ </p>
+ <p>
+ When you call <b>pcre2_match()</b>, as well as testing for invalid options, a
+diff --git a/doc/pcre2.txt b/doc/pcre2.txt
+index 693908ee..cc316178 100644
+--- a/doc/pcre2.txt
++++ b/doc/pcre2.txt
+@@ -6194,11 +6194,11 @@ JIT FAST PATH API
+        The  fast  path  function is called pcre2_jit_match(), and it takes ex-
+        actly the same arguments as pcre2_match(). However, the subject  string
+        must  be  specified  with  a  length; PCRE2_ZERO_TERMINATED is not sup-
+-       ported.  Unsupported  option  bits  (for  example,  PCRE2_ANCHORED  and
+-       PCRE2_ENDANCHORED)  are ignored, as is the PCRE2_NO_JIT option. The re-
+-       turn values are also the same  as  for  pcre2_match(),  plus  PCRE2_ER-
+-       ROR_JIT_BADOPTION if a matching mode (partial or complete) is requested
+-       that was not compiled.
++       ported. Unsupported option bits (for example, PCRE2_ANCHORED, PCRE2_EN-
++       DANCHORED, and  PCRE2_COPY_MATCHED_SUBJECT)  are  ignored,  as  is  the
++       PCRE2_NO_JIT  option.  The  return  values  are  also  the  same as for
++       pcre2_match(), plus PCRE2_ERROR_JIT_BADOPTION if a matching mode  (par-
++       tial or complete) is requested that was not compiled.
+        When  you call pcre2_match(), as well as testing for invalid options, a
+        number of other sanity checks are performed on the arguments. For exam-
+diff --git a/doc/pcre2jit.3 b/doc/pcre2jit.3
+index 95451b56..729d898f 100644
+--- a/doc/pcre2jit.3
++++ b/doc/pcre2jit.3
+@@ -444,10 +444,11 @@ processed by \fBpcre2_jit_compile()\fP).
+ The fast path function is called \fBpcre2_jit_match()\fP, and it takes exactly
+ the same arguments as \fBpcre2_match()\fP. However, the subject string must be
+ specified with a length; PCRE2_ZERO_TERMINATED is not supported. Unsupported
+-option bits (for example, PCRE2_ANCHORED and PCRE2_ENDANCHORED) are ignored, as
+-is the PCRE2_NO_JIT option. The return values are also the same as for
+-\fBpcre2_match()\fP, plus PCRE2_ERROR_JIT_BADOPTION if a matching mode (partial
+-or complete) is requested that was not compiled.
++option bits (for example, PCRE2_ANCHORED, PCRE2_ENDANCHORED, and
++PCRE2_COPY_MATCHED_SUBJECT) are ignored, as is the PCRE2_NO_JIT option. The
++return values are also the same as for \fBpcre2_match()\fP, plus
++PCRE2_ERROR_JIT_BADOPTION if a matching mode (partial or complete) is requested
++that was not compiled.
+ .P
+ When you call \fBpcre2_match()\fP, as well as testing for invalid options, a
+ number of other sanity checks are performed on the arguments. For example, if
+diff --git a/src/pcre2_jit_match_inc.h b/src/pcre2_jit_match_inc.h
+index 32d4c8a5..4163cf61 100644
+--- a/src/pcre2_jit_match_inc.h
++++ b/src/pcre2_jit_match_inc.h
+@@ -125,6 +125,16 @@ else if ((options & PCRE2_PARTIAL_SOFT) != 0)
+ if (functions == NULL || functions->executable_funcs[index] == NULL)
+   return match_data->rc = PCRE2_ERROR_JIT_BADOPTION;
++/* If the match data block was previously used with PCRE2_COPY_MATCHED_SUBJECT,
++free the memory that was obtained. */
++
++if ((match_data->flags & PCRE2_MD_COPIED_SUBJECT) != 0)
++  {
++  match_data->memctl.free((void *)match_data->subject,
++    match_data->memctl.memory_data);
++  match_data->flags &= ~PCRE2_MD_COPIED_SUBJECT;
++  }
++
+ /* Sanity checks should be handled by pcre2_match. */
+ arguments.str = subject + start_offset;
+ arguments.begin = subject;
+diff --git a/src/pcre2test_inc.h b/src/pcre2test_inc.h
+index 5d282435..a74e3368 100644
+--- a/src/pcre2test_inc.h
++++ b/src/pcre2test_inc.h
+@@ -5199,20 +5199,28 @@ for (gmatched = 0;; gmatched++)
+     /* If PCRE2_COPY_MATCHED_SUBJECT was set, check that things are as they
+     should be, but not for fast JIT, where it isn't supported. */
+-    if ((dat_datctl.options & PCRE2_COPY_MATCHED_SUBJECT) != 0 &&
+-        (pat_patctl.control & CTL_JITFAST) == 0)
++    if ((dat_datctl.options & PCRE2_COPY_MATCHED_SUBJECT) != 0)
+       {
+-      if ((match_data->flags & PCRE2_MD_COPIED_SUBJECT) == 0)
+-        cfprintf(clr_test_error, outfile,
+-          "** PCRE2 error: flag not set after copy_matched_subject\n");
++      if ((pat_patctl.control & CTL_JITFAST) != 0)
++        {
++        if ((match_data->flags & PCRE2_MD_COPIED_SUBJECT) != 0)
++          cfprintf(clr_test_error, outfile,
++            "** PCRE2 error: flag set after unsupported copy_matched_subject\n");
++        }
++      else
++        {
++        if ((match_data->flags & PCRE2_MD_COPIED_SUBJECT) == 0)
++          cfprintf(clr_test_error, outfile,
++            "** PCRE2 error: flag not set after copy_matched_subject\n");
+-      if (match_data->subject == pp)
+-        cfprintf(clr_test_error, outfile,
+-          "** PCRE2 error: copy_matched_subject has not copied\n");
++        if (match_data->subject == pp)
++          cfprintf(clr_test_error, outfile,
++            "** PCRE2 error: copy_matched_subject has not copied\n");
+-      if (memcmp(match_data->subject, pp, ulen) != 0)
+-        cfprintf(clr_test_error, outfile,
+-          "** PCRE2 error: copy_matched_subject mismatch\n");
++        if (memcmp(match_data->subject, pp, ulen) != 0)
++          cfprintf(clr_test_error, outfile,
++            "** PCRE2 error: copy_matched_subject mismatch\n");
++        }
+       }
+     /* If this is not the first time round a global loop, check that the
+@@ -5689,6 +5697,9 @@ pcre2_match_context *test_dat_context = NULL, *test_dat_context_copy = NULL;
+ pcre2_convert_context *test_con_context = NULL, *test_con_context_copy = NULL;
+ pcre2_match_data *test_match_data = NULL;
+ pcre2_code *test_compiled_code = NULL;
++#ifdef SUPPORT_JIT
++BOOL test_compiled_with_jit = FALSE;
++#endif
+ PCRE2_UCHAR pattern[] = { CHAR_A, CHAR_B, CHAR_C, 0 };
+ PCRE2_UCHAR callout_int_pattern[] = {
+   CHAR_LEFT_PARENTHESIS, CHAR_QUESTION_MARK, CHAR_C, CHAR_RIGHT_PARENTHESIS, 0 };
+@@ -5993,11 +6004,38 @@ ASSERT(rc == 0 && sizeval == 0, "pcre2_pattern_info(JIT)");
+ if (pcre2_jit_compile(test_compiled_code, PCRE2_JIT_COMPLETE) == 0)
+   {
++  test_compiled_with_jit = TRUE;
++
+   rc = pcre2_pattern_info(test_compiled_code, PCRE2_INFO_JITSIZE, &sizeval);
+   ASSERT(rc == 0 && sizeval > 0, "pcre2_pattern_info(JIT after compile)");
+   }
+ #endif
++/* ----------------------- Matching functions ------------------------------ */
++
++#ifdef SUPPORT_JIT
++
++/* Check that fast JIT releases a copied subject when reusing match data. */
++if (test_compiled_with_jit)
++  {
++  test_match_data = pcre2_match_data_create_from_pattern(test_compiled_code,
++    test_gen_context);
++  ASSERT(test_match_data != NULL, "pcre2_match_data_create_from_pattern(JIT)");
++
++  rc = pcre2_match(test_compiled_code, pattern, 3, 0,
++    PCRE2_COPY_MATCHED_SUBJECT, test_match_data, NULL);
++  ASSERT(rc == 1, "pcre2_match(COPY_MATCHED_SUBJECT)");
++
++  rc = pcre2_jit_match(test_compiled_code, subject_abcz, 4, 0, 0,
++    test_match_data, NULL);
++  ASSERT(rc == 1, "pcre2_jit_match(reused match data)");
++
++  pcre2_match_data_free(test_match_data);
++  test_match_data = NULL;
++  }
++
++#endif
++
+ /* ----------------------- POSIX functions --------------------------------- */
+ #if PCRE2_CODE_UNIT_WIDTH == 8
+diff --git a/testdata/testinput17 b/testdata/testinput17
+index 08fd72e0..9d728965 100644
+--- a/testdata/testinput17
++++ b/testdata/testinput17
+@@ -298,6 +298,7 @@
+     
+ /abc/jitfast
+     abc
++    abc\=copy_matched_subject
+     abc\=no_jit 
+     
+ # ---- 
+diff --git a/testdata/testoutput17 b/testdata/testoutput17
+index 6d550084..773ec18a 100644
+--- a/testdata/testoutput17
++++ b/testdata/testoutput17
+@@ -542,6 +542,8 @@ Failed: error -47: match limit exceeded
+     
+ /abc/jitfast
+     abc
++ 0: abc (JIT)
++    abc\=copy_matched_subject
+  0: abc (JIT)
+     abc\=no_jit 
+  0: abc (JIT)
+commit 1cad831209af67d24298c301a74c615d3a6d57eb
+Author: Carlo Marcelo Arenas Belón <carenas@gmail.com>
+Date:   Sat Aug 22 04:02:30 2026 -0700
+
+    pcre2test: honor no_jit when used with jitfast (#946)
+    
+    `pcre2_jit_match()` ignores the PCRE2_NO_JIT option, so teach pcre2test
+    to avoid calling it if the subject modifier that sets that option is
+    used together with the option to call it directly.
+    
+    While at it, make jitverify more reliable and add a unittest to validate
+    that PCRE2_NO_JIT is ignored in the fast JIt path.
+
+diff --git a/doc/html/pcre2test.html b/doc/html/pcre2test.html
+index 5160acc9..d2534780 100644
+--- a/doc/html/pcre2test.html
++++ b/doc/html/pcre2test.html
+@@ -863,7 +863,7 @@ when it can never be used.
+ The <b>framesize</b> modifier shows the size, in bytes, of each storage frame
+ used by <b>pcre2_match()</b> for handling backtracking. The size depends on the
+ number of capturing parentheses in the pattern. A vector of these frames is
+-used at matching time; its overall size is shown when the <b>heaframes_size</b>
++used at matching time; its overall size is shown when the <b>heapframes_size</b>
+ subject modifier is set.
+ </p>
+ <p>
+diff --git a/doc/pcre2test.1 b/doc/pcre2test.1
+index 897552a2..c5bc9317 100644
+--- a/doc/pcre2test.1
++++ b/doc/pcre2test.1
+@@ -811,7 +811,7 @@ when it can never be used.
+ The \fBframesize\fP modifier shows the size, in bytes, of each storage frame
+ used by \fBpcre2_match()\fP for handling backtracking. The size depends on the
+ number of capturing parentheses in the pattern. A vector of these frames is
+-used at matching time; its overall size is shown when the \fBheaframes_size\fP
++used at matching time; its overall size is shown when the \fBheapframes_size\fP
+ subject modifier is set.
+ .P
+ The \fBcallout_info\fP modifier requests information about all the callouts in
+diff --git a/doc/pcre2test.txt b/doc/pcre2test.txt
+index 819fe76e..fad3b8f3 100644
+--- a/doc/pcre2test.txt
++++ b/doc/pcre2test.txt
+@@ -787,7 +787,7 @@ PATTERN MODIFIERS
+        used by pcre2_match() for handling backtracking. The  size  depends  on
+        the  number  of capturing parentheses in the pattern. A vector of these
+        frames is used at matching time; its overall size  is  shown  when  the
+-       heaframes_size subject modifier is set.
++       heapframes_size subject modifier is set.
+        The  callout_info  modifier requests information about all the callouts
+        in the pattern. A list of them is output at the end of any other infor-
+diff --git a/src/pcre2test_inc.h b/src/pcre2test_inc.h
+index 72767916..69c64f73 100644
+--- a/src/pcre2test_inc.h
++++ b/src/pcre2test_inc.h
+@@ -3165,7 +3165,8 @@ for (;;)
+       dat_context, dfa_workspace, DFA_WS_DIMENSION);
+     }
+-  else if ((pat_patctl.control & CTL_JITFAST) != 0)
++  else if ((pat_patctl.control & CTL_JITFAST) != 0 &&
++           (dat_datctl.options & PCRE2_NO_JIT) == 0)
+     capcount = pcre2_jit_match(compiled_code, pp, ulen, dat_datctl.offset,
+       dat_datctl.options, match_data, dat_context);
+@@ -4747,7 +4748,8 @@ if (dat_datctl.replacement[0] != MOD_STR_UNSET)
+         dat_datctl.offset, dat_datctl.options, match_data,
+         use_dat_context, dfa_workspace, DFA_WS_DIMENSION);
+       }
+-    else if ((pat_patctl.control & CTL_JITFAST) != 0)
++    else if ((pat_patctl.control & CTL_JITFAST) != 0 &&
++             (dat_datctl.options & PCRE2_NO_JIT) == 0)
+       {
+       (void)pcre2_jit_match(compiled_code, pp, arg_ulen, dat_datctl.offset,
+         dat_datctl.options, match_data, use_dat_context);
+@@ -4990,7 +4992,7 @@ for (gmatched = 0;; gmatched++)
+   /* When matching is via pcre2_match(), we will detect the use of JIT via the
+   stack callback function. */
+-  jit_was_used = (pat_patctl.control & CTL_JITFAST) != 0;
++  jit_was_used = FALSE;
+   /* Do timing if required. */
+@@ -5021,7 +5023,8 @@ for (gmatched = 0;; gmatched++)
+         }
+       }
+-    else if ((pat_patctl.control & CTL_JITFAST) != 0)
++    else if ((pat_patctl.control & CTL_JITFAST) != 0 &&
++             (dat_datctl.options & PCRE2_NO_JIT) == 0)
+       {
+       start_time = clock();
+       for (i = 0; i < timeitm; i++)
+@@ -5105,9 +5108,11 @@ for (gmatched = 0;; gmatched++)
+       }
+     else
+       {
+-      if ((pat_patctl.control & CTL_JITFAST) != 0)
+-        capcount = pcre2_jit_match(compiled_code, pp, arg_ulen, dat_datctl.offset,
+-          dat_datctl.options | g_notempty, match_data, use_dat_context);
++      if ((pat_patctl.control & CTL_JITFAST) != 0 &&
++          (dat_datctl.options & PCRE2_NO_JIT) == 0)
++        capcount = pcre2_jit_match(compiled_code, pp, arg_ulen,
++          dat_datctl.offset, dat_datctl.options | g_notempty, match_data,
++          use_dat_context);
+       else
+         capcount = pcre2_match(compiled_code, pp, arg_ulen, dat_datctl.offset,
+           dat_datctl.options | g_notempty, match_data, use_dat_context);
+@@ -5142,12 +5147,15 @@ for (gmatched = 0;; gmatched++)
+           }
+         else
+           {
+-          if ((pat_patctl.control & CTL_JITFAST) != 0)
+-            capcount = pcre2_jit_match(compiled_code, pp, arg_ulen, dat_datctl.offset,
+-              dat_datctl.options | g_notempty, match_data, use_dat_context);
++          if ((pat_patctl.control & CTL_JITFAST) != 0 &&
++              (dat_datctl.options & PCRE2_NO_JIT) == 0)
++            capcount = pcre2_jit_match(compiled_code, pp, arg_ulen,
++              dat_datctl.offset, dat_datctl.options | g_notempty, match_data,
++              use_dat_context);
+           else
+-            capcount = pcre2_match(compiled_code, pp, arg_ulen, dat_datctl.offset,
+-              dat_datctl.options | g_notempty, match_data, use_dat_context);
++            capcount = pcre2_match(compiled_code, pp, arg_ulen,
++              dat_datctl.offset, dat_datctl.options | g_notempty, match_data,
++              use_dat_context);
+           }
+         mallocs_until_failure = INT_MAX;
+@@ -5207,12 +5215,20 @@ for (gmatched = 0;; gmatched++)
+       return PR_ABEND;
+       }
++    /* tracking JIT with jitverify needs a context, but in cases where one
++    wasn't available, can fallback to the match_data status */
++
++    if ((dat_datctl.control & CTL_NULLCONTEXT) != 0 &&
++        (pat_patctl.control & CTL_JITVERIFY) != 0)
++      jit_was_used = match_data->matchedby == PCRE2_MATCHEDBY_JIT;
++
+     /* If PCRE2_COPY_MATCHED_SUBJECT was set, check that things are as they
+     should be, but not for fast JIT, where it isn't supported. */
+     if ((dat_datctl.options & PCRE2_COPY_MATCHED_SUBJECT) != 0)
+       {
+-      if ((pat_patctl.control & CTL_JITFAST) != 0)
++      if ((pat_patctl.control & CTL_JITFAST) != 0 &&
++          (dat_datctl.options & PCRE2_NO_JIT) == 0)
+         {
+         if ((match_data->flags & PCRE2_MD_COPIED_SUBJECT) != 0)
+           cfprintf(clr_test_error, outfile,
+@@ -6026,9 +6042,11 @@ if (pcre2_jit_compile(test_compiled_code, PCRE2_JIT_COMPLETE) == 0)
+ #ifdef SUPPORT_JIT
+-/* Check that fast JIT releases a copied subject when reusing match data. */
+ if (test_compiled_with_jit)
+   {
++
++/* Check that fast JIT releases a copied subject when reusing match data. */
++
+   test_match_data = pcre2_match_data_create_from_pattern(test_compiled_code,
+     test_gen_context);
+   ASSERT(test_match_data != NULL, "pcre2_match_data_create_from_pattern(JIT)");
+@@ -6043,6 +6061,22 @@ if (test_compiled_with_jit)
+   pcre2_match_data_free(test_match_data);
+   test_match_data = NULL;
++
++/* Check that fast JIT ignores PCRE2_NO_JIT */
++
++  test_match_data = pcre2_match_data_create(100000, test_gen_context);
++  ASSERT(test_match_data != NULL, "pcre2_match_data_create(100000)");
++  ASSERT(pcre2_get_ovector_count(test_match_data) == 65535,
++    "pcre2_get_ovector_count(UINT32_MAX) <= UINT16_MAX)");
++
++  rc = pcre2_jit_match(test_compiled_code, subject_abcz, 4, 0, PCRE2_NO_JIT,
++    test_match_data, NULL);
++  ASSERT(rc == 1 && (test_match_data->matchedby == PCRE2_MATCHEDBY_JIT),
++    "pcre2_jit_match(ignore PCRE2_NO_JIT");
++
++  pcre2_match_data_free(test_match_data);
++  test_match_data = NULL;
++
+   }
+ #endif
+diff --git a/testdata/testinput17 b/testdata/testinput17
+index e6dbbe42..a02e6be2 100644
+--- a/testdata/testinput17
++++ b/testdata/testinput17
+@@ -295,12 +295,29 @@
+ /abc/
+     abc
+     abc\=no_jit 
+-    
++
++/(*NO_JIT)abc/
++    abc
++
+ /abc/jitfast
+     abc
+-    abc\=copy_matched_subject
+     abc\=no_jit 
+-    
++
++/(*NO_JIT)abc/jitfast
++\= Expect error
++    abc
++
++# Do not leak a previously copied subject with jitfast (#920)
++
++/abc/jitfast
++    abc\=copy_matched_subject,no_jit
++    abc
++
++/abc/jitfast
++    abc\=copy_matched_subject
++    abc\=null_context
++    abc\=null_context,no_jit
++
+ # ---- 
+ /[aC]/mg,firstline,newline=lf
+diff --git a/testdata/testoutput17 b/testdata/testoutput17
+index 11f032d8..c678587f 100644
+--- a/testdata/testoutput17
++++ b/testdata/testoutput17
+@@ -539,15 +539,38 @@ Failed: error -47: match limit exceeded
+  0: abc (JIT)
+     abc\=no_jit 
+  0: abc
+-    
++
++/(*NO_JIT)abc/
++    abc
++ 0: abc
++
++/abc/jitfast
++    abc
++ 0: abc (JIT)
++    abc\=no_jit 
++ 0: abc
++
++/(*NO_JIT)abc/jitfast
++\= Expect error
++    abc
++Failed: error -45: bad JIT option
++
++# Do not leak a previously copied subject with jitfast (#920)
++
+ /abc/jitfast
++    abc\=copy_matched_subject,no_jit
++ 0: abc
+     abc
+  0: abc (JIT)
++
++/abc/jitfast
+     abc\=copy_matched_subject
+  0: abc (JIT)
+-    abc\=no_jit 
++    abc\=null_context
+  0: abc (JIT)
+-    
++    abc\=null_context,no_jit
++ 0: abc
++
+ # ---- 
+ /[aC]/mg,firstline,newline=lf
diff --git a/patches/pcre2-10.48-Fix-allocation-byte-sizing.patch b/patches/pcre2-10.48-Fix-allocation-byte-sizing.patch
new file mode 100644 (file)
index 0000000..98295d8
--- /dev/null
@@ -0,0 +1,54 @@
+commit 8156b3989a82f2ddf9504d8248496e9b124be7f3
+Author: Ilia Alshanetsky <ilia@ilia.ws>
+Date:   Sun Aug 9 07:15:03 2026 -0400
+
+    Use CU2BYTES for byte sizing in two allocation sites (#909)
+    
+    Two allocation sites multiplied by PCRE2_CODE_UNIT_WIDTH (the bit width:
+    8, 16, or 32) where the CU2BYTES(x) byte-count helper is intended. The
+    result over-allocates by the code-unit byte width: 8x in 8-bit mode, 16x
+    in 16-bit, 32x in 32-bit. Subsequent memcpy calls already use CU2BYTES
+    correctly, so no out-of-bounds write occurs; the over-allocation is
+    leaked until the buffer is freed.
+    
+    Also guard each site against integer overflow in
+    sizeof(pcre2_memctl) + CU2BYTES(N + 1) by rejecting N greater than
+    (PCRE2_SIZE_MAX - sizeof(pcre2_memctl)) / CU2BYTES(1) - 1.
+
+diff --git a/src/pcre2_convert.c b/src/pcre2_convert.c
+index ad7312ab..8a2b293d 100644
+--- a/src/pcre2_convert.c
++++ b/src/pcre2_convert.c
+@@ -1215,9 +1215,11 @@ for (int i = 0; i < 2; i++)
+   /* Allocate memory for the buffer, with hidden space for an allocator at
+   the start. The next time round the loop runs the conversion for real. */
+-  allocated = PRIV(memctl_malloc)(sizeof(pcre2_memctl) +
+-    (*bufflenptr + 1)*PCRE2_CODE_UNIT_WIDTH, (pcre2_memctl *)ccontext);
+-  if (allocated == NULL)
++  if (*bufflenptr > ((PCRE2_SIZE_MAX - sizeof(pcre2_memctl)) /
++        CU2BYTES(1)) - 1 ||
++      (allocated = PRIV(memctl_malloc)(sizeof(pcre2_memctl) +
++        CU2BYTES(*bufflenptr + 1),
++        (pcre2_memctl *)ccontext)) == NULL)
+     {
+     *bufflenptr = 0;  /* Error offset */
+     return PCRE2_ERROR_NOMEMORY;
+diff --git a/src/pcre2_substring.c b/src/pcre2_substring.c
+index f68b464e..a6f5277a 100644
+--- a/src/pcre2_substring.c
++++ b/src/pcre2_substring.c
+@@ -210,9 +210,10 @@ PCRE2_SIZE size;
+ PCRE2_UCHAR *yield;
+ rc = pcre2_substring_length_bynumber(match_data, stringnumber, &size);
+ if (rc < 0) return rc;
+-yield = PRIV(memctl_malloc)(sizeof(pcre2_memctl) +
+-  (size + 1)*PCRE2_CODE_UNIT_WIDTH, (pcre2_memctl *)match_data);
+-if (yield == NULL) return PCRE2_ERROR_NOMEMORY;
++if (size > ((PCRE2_SIZE_MAX - sizeof(pcre2_memctl)) / CU2BYTES(1)) - 1 ||
++    (yield = PRIV(memctl_malloc)(sizeof(pcre2_memctl) +
++      CU2BYTES(size + 1), (pcre2_memctl *)match_data)) == NULL)
++  return PCRE2_ERROR_NOMEMORY;
+ yield = (PCRE2_UCHAR *)(((char *)yield) + sizeof(pcre2_memctl));
+ if (size != 0) memcpy(yield, match_data->subject + match_data->ovector[stringnumber*2],
+   CU2BYTES(size));
diff --git a/patches/pcre2-10.48-Fix-character-list-generator.patch b/patches/pcre2-10.48-Fix-character-list-generator.patch
new file mode 100644 (file)
index 0000000..6db9a28
--- /dev/null
@@ -0,0 +1,113 @@
+commit f483bce249c537c482d686234257017dcfb72aaf
+Author: Zoltan Herczeg <zherczeg7@gmail.com>
+Date:   Tue Nov 18 15:19:41 2025 +0100
+
+    Fix character list generator (#841)
+
+diff --git a/src/pcre2_compile_class.c b/src/pcre2_compile_class.c
+index 55b641c1..c6f30d6f 100644
+--- a/src/pcre2_compile_class.c
++++ b/src/pcre2_compile_class.c
+@@ -721,9 +721,13 @@ while (TRUE)
+   else
+     cranges->char_lists_types |= tmp1 << tmp2;
+-  if (range_start < XCL_CHAR_LIST_LOW_16_START) break;
++  if (range_end < XCL_CHAR_LIST_LOW_16_START || tmp2 == 0)
++    {
++    PCRE2_ASSERT(range_start < XCL_CHAR_LIST_LOW_16_START);
++    break;
++    }
+-  PCRE2_ASSERT(tmp2 >= XCL_TYPE_BIT_LEN);
++  PCRE2_ASSERT((tmp2 % XCL_TYPE_BIT_LEN) == 0);
+   char_list_end = char_list_start - 1;
+   char_list_start = *char_list_next++;
+   tmp1 = 0;
+diff --git a/src/pcre2_internal.h b/src/pcre2_internal.h
+index aa794095..2675e58e 100644
+--- a/src/pcre2_internal.h
++++ b/src/pcre2_internal.h
+@@ -1518,7 +1518,7 @@ High16 and High32: the highest bit is always one
+ The items are ordered in increasing order, so binary search can be
+ used to find the lower bound of an input character. The lower bound
+ is the highest item, which value is less or equal than the input
+-character. If the lower bit of the item is cleard, or the character
++character. If the lower bit of the item is cleared, or the character
+ stored in the item equals to the input character, the input
+ character is in the character list. */
+@@ -1539,14 +1539,19 @@ character is in the character list. */
+ #define XCL_CHAR_LIST_HIGH_32_END 0xffffffff
+ #define XCL_CHAR_LIST_HIGH_32_ADD 0x80000000
+-/* Mask for getting the descriptors of character list ranges.
+-Each descriptor has XCL_TYPE_BIT_LEN bits, and can be processed
+-by XCL_BEGIN_WITH_RANGE and XCL_ITEM_COUNT_MASK macros. */
++/* Mask and length values for getting the descriptors of
++all character list ranges. The bit length of each descriptor
++is XCL_TYPE_BIT_LEN so the total size is 4*XCL_TYPE_BIT_LEN
++(currently 12 bit). This data is stored for all four character
++lists, even if no characters are present in a list. */
+ #define XCL_TYPE_MASK 0xfff
+ #define XCL_TYPE_BIT_LEN 3
+-/* If this bit is set, the first item of the character list is the
+-end of a range, which started before the starting character of the
+-character list. */
++/* If this bit is set for a character class, the first item of the
++character list is the end of a range, which started before the
++starting character of the character list. If this bit is set, and
++no characters are present in the list, the whole character class
++is part of a range. E.g: [\x{500}-\x{12000}] covers the entire
++0x8000-0xffff range. */
+ #define XCL_BEGIN_WITH_RANGE 0x4
+ /* Number of items in the character list: 0, 1, or 2. The value 3
+ represents that the item count is stored at the begining of the
+diff --git a/testdata/testinput5 b/testdata/testinput5
+index 7f9f6a2d..d47e0c1e 100644
+--- a/testdata/testinput5
++++ b/testdata/testinput5
+@@ -2892,6 +2892,12 @@
+ /([\x{6535}\x{6536}\x{6538}\x{6539}\x{653b}\x{653c}\x{653e}\x{653f}\x{6541}\x{6542}\x{8000}-\x{ffff}]#)+/B,utf
+   \x{6534}#\x{6537}#\x{653a}#\x{653d}#\x{6540}#\x{6543}#\x{7fff}#\x{6535}#\x{6536}#\x{6538}#\x{6539}#\x{653b}#\x{653c}#\x{653e}#\x{653f}#\x{6541}#\x{6542}#\x{8000}#\x{c246}#\x{ffff}
++/[\x{ff}\x{100}\x{8000}\x{8002}\x{8004}\x{8006}\x{8008}\x{800a}\x{800c}\x{800e}]+/B,utf
++  \x{ff}\x{100}\x{8000}\x{800a}\x{800e}\x{101}
++
++/[\x{ff}-\x{104}\x{8000}\x{8002}\x{8004}\x{8006}\x{8008}\x{800a}\x{800c}\x{800e}]+/B,utf
++  \x{ff}\x{100}\x{101}\x{104}\x{8000}\x{800a}\x{800e}\x{105}
++
+ /[[:xdigit:]\x{400}-\x{600}]+/utf,ucp
+   !a0\x{400}\x{600}9\x{3ff}
+diff --git a/testdata/testoutput5 b/testdata/testoutput5
+index fd36974d..82b3abe9 100644
+--- a/testdata/testoutput5
++++ b/testdata/testoutput5
+@@ -6339,6 +6339,26 @@ Failed: error 115 at offset 53: reference to non-existent subpattern
+  0: \x{6535}#\x{6536}#\x{6538}#\x{6539}#\x{653b}#\x{653c}#\x{653e}#\x{653f}#\x{6541}#\x{6542}#\x{8000}#\x{c246}#
+  1: \x{c246}#
++/[\x{ff}\x{100}\x{8000}\x{8002}\x{8004}\x{8006}\x{8008}\x{800a}\x{800c}\x{800e}]+/B,utf
++------------------------------------------------------------------
++        Bra
++        [\xff\x{100}\x{8000}\x{8002}\x{8004}\x{8006}\x{8008}\x{800a}\x{800c}\x{800e}]++
++        Ket
++        End
++------------------------------------------------------------------
++  \x{ff}\x{100}\x{8000}\x{800a}\x{800e}\x{101}
++ 0: \x{ff}\x{100}\x{8000}\x{800a}\x{800e}
++
++/[\x{ff}-\x{104}\x{8000}\x{8002}\x{8004}\x{8006}\x{8008}\x{800a}\x{800c}\x{800e}]+/B,utf
++------------------------------------------------------------------
++        Bra
++        [\xff\x{100}-\x{104}\x{8000}\x{8002}\x{8004}\x{8006}\x{8008}\x{800a}\x{800c}\x{800e}]++
++        Ket
++        End
++------------------------------------------------------------------
++  \x{ff}\x{100}\x{101}\x{104}\x{8000}\x{800a}\x{800e}\x{105}
++ 0: \x{ff}\x{100}\x{101}\x{104}\x{8000}\x{800a}\x{800e}
++
+ /[[:xdigit:]\x{400}-\x{600}]+/utf,ucp
+   !a0\x{400}\x{600}9\x{3ff}
+  0: a0\x{400}\x{600}9
diff --git a/patches/pcre2-10.48-Fix-compiler-integer-overflows.patch b/patches/pcre2-10.48-Fix-compiler-integer-overflows.patch
new file mode 100644 (file)
index 0000000..53ee06e
--- /dev/null
@@ -0,0 +1,200 @@
+commit ec9c286d5c10cf1c388b58a442ccefded42254fd
+Author: Nicholas Wilson <nicholas@nicholaswilson.me.uk>
+Date:   Thu Aug 27 16:52:16 2026 +0100
+
+    Fix compiler integer overflows; see GHSA-fmgr-6ggq-9859 for details
+
+diff --git a/src/pcre2_compile.c b/src/pcre2_compile.c
+index 1081cf64..32cb32f6 100644
+--- a/src/pcre2_compile.c
++++ b/src/pcre2_compile.c
+@@ -6195,7 +6195,8 @@ for (;; pptr++)
+     if (meta < META_ASTERISK || meta > META_MINMAX_QUERY)
+       {
+-      if (OFLOW_MAX - *lengthptr < (PCRE2_SIZE)(code - orig_code))
++      if (*lengthptr > OFLOW_MAX ||
++          OFLOW_MAX - *lengthptr < (PCRE2_SIZE)(code - orig_code))
+         {
+         *errorcodeptr = ERR20;   /* Integer overflow */
+         cb->erroroffset = 0;
+@@ -8802,7 +8803,8 @@ for (;;)
+     *reqcuflagsptr = reqcuflags;
+     if (lengthptr != NULL)
+       {
+-      if (OFLOW_MAX - *lengthptr < length)
++      if (*lengthptr > MAX_PATTERN_SIZE ||
++          MAX_PATTERN_SIZE - *lengthptr < length)
+         {
+         *errorcodeptr = ERR20;
+         return 0;
+@@ -8825,6 +8827,19 @@ for (;;)
+     {
+     code = *codeptr + 1 + LINK_SIZE + skipunits;
+     length += 1 + LINK_SIZE;
++
++    /* Move the accumulated length into *lengthptr, providing the next call to
++    compile_branch with as much space in &length and &code as the first did. */
++
++    if (*lengthptr > MAX_PATTERN_SIZE ||
++        MAX_PATTERN_SIZE - *lengthptr < length)
++      {
++      *errorcodeptr = ERR20;
++      cb->erroroffset = 0;
++      return 0;
++      }
++    *lengthptr += length;
++    length = 0;
+     }
+   else
+     {
+@@ -10851,7 +10866,8 @@ if (errorcode != 0) goto HAD_CB_ERROR;  /* Offset is in cb.erroroffset */
+ #if defined SUPPORT_WIDE_CHARS
+ PCRE2_ASSERT((cb.char_lists_size & 0x3) == 0);
+ if (length > MAX_PATTERN_SIZE ||
+-    MAX_PATTERN_SIZE - length < (cb.char_lists_size / sizeof(PCRE2_UCHAR)))
++    BYTES2CU(cb.char_lists_size) > MAX_PATTERN_SIZE ||
++    MAX_PATTERN_SIZE - length < BYTES2CU(cb.char_lists_size))
+ #else
+ if (length > MAX_PATTERN_SIZE)
+ #endif
+@@ -10876,11 +10892,36 @@ if (cb.char_lists_size != 0)
+   /* Align to 32 bit first. This ensures the
+   allocated area will also be 32 bit aligned. */
+   re_blocksize = (PCRE2_SIZE)CLIST_ALIGN_TO(re_blocksize, sizeof(uint32_t));
++#else
++  /* Already 32 bit aligned. */
+ #endif
++
++  /* We have bounded the length and BYTES2CU(char_lists_size) to
++  MAX_PATTERN_SIZE units, however (with 32-bit code units) char_lists_size
++  in bytes could still be extremely close to (or greater than) SIZE_MAX, so
++  we require another overflow check. */
++
++  if (cb.char_lists_size > PCRE2_SIZE_MAX - re_blocksize)
++    {
++    errorcode = ERR20;
++    cb.erroroffset = 0;
++    goto HAD_CB_ERROR;
++    }
++
+   re_blocksize += cb.char_lists_size;
+   }
+ #endif
++if (length > BYTES2CU(PCRE2_SIZE_MAX - re_blocksize))
++  {
++  /* Given the current value of 2^30 for MAX_PATTERN_SIZE, this block is only
++  reachable when both PCRE2_CODE_UNIT_WIDTH >= 16 and sizeof(size_t) is
++  32 bits. */
++  errorcode = ERR20;
++  cb.erroroffset = 0;
++  goto HAD_CB_ERROR;
++  }
++
+ re_blocksize += CU2BYTES(length);
+ if (re_blocksize > ccontext->max_pattern_compiled_length)
+@@ -10890,7 +10931,15 @@ if (re_blocksize > ccontext->max_pattern_compiled_length)
+   goto HAD_CB_ERROR;
+   }
++if (sizeof(pcre2_real_code) > PCRE2_SIZE_MAX - re_blocksize)
++  {
++  errorcode = ERR20;
++  cb.erroroffset = 0;
++  goto HAD_CB_ERROR;
++  }
++
+ re_blocksize += sizeof(pcre2_real_code);
++
+ re = (pcre2_real_code *)
+   ccontext->memctl.malloc(re_blocksize, ccontext->memctl.memory_data);
+ if (re == NULL)
+diff --git a/src/pcre2_compile_class.c b/src/pcre2_compile_class.c
+index c6f30d6f..c0606643 100644
+--- a/src/pcre2_compile_class.c
++++ b/src/pcre2_compile_class.c
+@@ -498,7 +498,7 @@ static const uint32_t char_list_starts[] = {
+ static class_ranges *
+ compile_optimize_class(uint32_t *start_ptr, uint32_t options,
+-  uint32_t xoptions, compile_block *cb)
++  uint32_t xoptions, int *errorcodeptr, compile_block *cb)
+ {
+ class_ranges* cranges;
+ uint32_t *ptr;
+@@ -538,12 +538,23 @@ PCRE2_ASSERT((range_list_size & 0x1) == 0);
+ total_size = range_list_size +
+    ((range_list_size >= 2) ? CHAR_LIST_EXTRA_SIZE : 0);
++if (total_size > (PCRE2_SIZE_MAX - sizeof(class_ranges)) / sizeof(uint32_t))
++  {
++  *errorcodeptr = ERR20;
++  cb->erroroffset = 0;
++  return NULL;
++  }
+ cranges = cb->cx->memctl.malloc(
+   sizeof(class_ranges) + total_size * sizeof(uint32_t),
+   cb->cx->memctl.memory_data);
+-if (cranges == NULL) return NULL;
++if (cranges == NULL)
++  {
++  *errorcodeptr = ERR21;
++  cb->erroroffset = 0;
++  return NULL;
++  }
+ cranges->header.next = NULL;
+ #ifdef PCRE2_DEBUG
+@@ -1120,13 +1131,10 @@ if (utf)
+   {
+   if (lengthptr != NULL)
+     {
+-    cranges = compile_optimize_class(pptr, options, xoptions, cb);
++    cranges = compile_optimize_class(pptr, options, xoptions, errorcodeptr, cb);
+     if (cranges == NULL)
+-      {
+-      *errorcodeptr = ERR21;
+       return NULL;
+-      }
+     /* Caching the pre-processed character ranges. */
+     if (cb->last_data != NULL)
+@@ -1759,18 +1767,17 @@ if ((xclass_props & XCLASS_REQUIRED) != 0)
+       *lengthptr += 1 + LINK_SIZE;
+ #endif
+-      cb->char_lists_size += char_lists_size;
+-
+-      char_lists_size /= sizeof(PCRE2_UCHAR);
++      PCRE2_ASSERT(BYTES2CU(cb->char_lists_size) <= MAX_PATTERN_SIZE);
+-      /* Storage space for character lists is included
+-      in the maximum pattern size. */
+-      if (*lengthptr > MAX_PATTERN_SIZE ||
+-          MAX_PATTERN_SIZE - *lengthptr < char_lists_size)
++      if (char_lists_size > PCRE2_SIZE_MAX - cb->char_lists_size ||
++          BYTES2CU(char_lists_size) > MAX_PATTERN_SIZE ||
++          BYTES2CU(cb->char_lists_size) > MAX_PATTERN_SIZE - BYTES2CU(char_lists_size))
+         {
+         *errorcodeptr = ERR20;   /* Pattern is too large */
+         return NULL;
+         }
++
++      cb->char_lists_size += char_lists_size;
+       }
+     else
+       {
+@@ -1793,6 +1800,8 @@ if ((xclass_props & XCLASS_REQUIRED) != 0)
+       Each list is aligned to 32 bit with an optional unused
+       16 bit value at the beginning of the character list. */
++      PCRE2_ASSERT(char_lists_size <= PCRE2_SIZE_MAX - cb->char_lists_size);
++
+       cb->char_lists_size += char_lists_size;
+       data = (uint8_t*)cb->start_code - cb->char_lists_size;
diff --git a/patches/pcre2-10.48-Fix-invalid-UTF-backwards-scans.patch b/patches/pcre2-10.48-Fix-invalid-UTF-backwards-scans.patch
new file mode 100644 (file)
index 0000000..5a4170a
--- /dev/null
@@ -0,0 +1,212 @@
+commit 4889caf31a4c5a6b3c051f0031bf2dbd78f2c287
+Author: Nicholas Wilson <nicholas@nicholaswilson.me.uk>
+Date:   Thu Aug 27 16:52:16 2026 +0100
+
+    Fix invalid UTF backwards-scan reads; see GHSA-9qww-pwc4-77qq for details
+
+diff --git a/src/pcre2_extuni.c b/src/pcre2_extuni.c
+index 1b7f04b4..fea098a7 100644
+--- a/src/pcre2_extuni.c
++++ b/src/pcre2_extuni.c
+@@ -54,12 +54,12 @@ support, because some compilers do not like functionless source files. */
+ #ifndef SUPPORT_UNICODE
+ PCRE2_SPTR
+-PRIV(extuni)(uint32_t c, PCRE2_SPTR eptr, PCRE2_SPTR start_subject,
++PRIV(extuni)(uint32_t c, PCRE2_SPTR eptr, PCRE2_SPTR check_subject,
+   PCRE2_SPTR end_subject, BOOL utf, int *xcount)
+ {
+ (void)c;
+ (void)eptr;
+-(void)start_subject;
++(void)check_subject;
+ (void)end_subject;
+ (void)utf;
+ (void)xcount;
+@@ -80,7 +80,7 @@ same behaviour.
+ Arguments:
+   c              the first character
+   eptr           pointer to next character
+-  start_subject  pointer to start of subject
++  check_subject  pointer to start of validated subject
+   end_subject    pointer to end of subject
+   utf            TRUE if in UTF mode
+   xcount         pointer to count of additional characters,
+@@ -90,7 +90,7 @@ Returns:         pointer after the end of the sequence
+ */
+ PCRE2_SPTR
+-PRIV(extuni)(uint32_t c, PCRE2_SPTR eptr, PCRE2_SPTR start_subject,
++PRIV(extuni)(uint32_t c, PCRE2_SPTR eptr, PCRE2_SPTR check_subject,
+   PCRE2_SPTR end_subject, BOOL utf, int *xcount)
+ {
+ BOOL was_ep_ZWJ = FALSE;
+@@ -121,7 +121,7 @@ while (eptr < end_subject)
+     /* bptr is pointing to the left-hand character */
+-    while (bptr > start_subject)
++    while (bptr > check_subject)
+       {
+       bptr--;
+       if (utf)
+diff --git a/src/pcre2_match.c b/src/pcre2_match.c
+index a5a8421f..966576e1 100644
+--- a/src/pcre2_match.c
++++ b/src/pcre2_match.c
+@@ -2895,7 +2895,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode,
+     else
+       {
+       GETCHARINCTEST(fc, Feptr);
+-      Feptr = PRIV(extuni)(fc, Feptr, mb->start_subject, mb->end_subject, utf,
++      Feptr = PRIV(extuni)(fc, Feptr, mb->check_subject, mb->end_subject, utf,
+         NULL);
+       }
+     CHECK_PARTIAL();
+@@ -3246,7 +3246,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode,
+           else
+             {
+             GETCHARINCTEST(fc, Feptr);
+-            Feptr = PRIV(extuni)(fc, Feptr, mb->start_subject,
++            Feptr = PRIV(extuni)(fc, Feptr, mb->check_subject,
+               mb->end_subject, utf, NULL);
+             }
+           CHECK_PARTIAL();
+@@ -4071,7 +4071,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode,
+           else
+             {
+             GETCHARINCTEST(fc, Feptr);
+-            Feptr = PRIV(extuni)(fc, Feptr, mb->start_subject, mb->end_subject,
++            Feptr = PRIV(extuni)(fc, Feptr, mb->check_subject, mb->end_subject,
+               utf, NULL);
+             }
+           CHECK_PARTIAL();
+@@ -4660,7 +4660,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode,
+           else
+             {
+             GETCHARINCTEST(fc, Feptr);
+-            Feptr = PRIV(extuni)(fc, Feptr, mb->start_subject, mb->end_subject,
++            Feptr = PRIV(extuni)(fc, Feptr, mb->check_subject, mb->end_subject,
+               utf, NULL);
+             }
+           CHECK_PARTIAL();
+@@ -6243,7 +6243,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode,
+       {
+       for (i = 0; i < Lmax; i++)
+         {
+-        if (Feptr == mb->start_subject)
++        if (Feptr <= mb->check_subject)
+           {
+           if (i < Lmin) RRETURN(MATCH_NOMATCH);
+           Lmax = i;
+diff --git a/testdata/testinput10 b/testdata/testinput10
+index d9e6ba8c..bfa9dad8 100644
+--- a/testdata/testinput10
++++ b/testdata/testinput10
+@@ -585,6 +585,16 @@
+     AAA\x80BXYZ 
+     AAA\x80BBXYZ 
++# Backward scans must not enter the invalid prefix before check_subject.
++
++/(?<=a{1,2})X/utf,match_invalid_utf
++\= Expect no match
++    \x80X
++
++/\X\X/utf,match_invalid_utf
++\= Expect no match
++    \x80\x{1f1e6}\x{1f1e7}
++
+ /(?<=(.))/utf,match_invalid_utf
+     x\x80
+     \x{10000}\x80
+diff --git a/testdata/testinput12 b/testdata/testinput12
+index 01cc76a4..c4a89a26 100644
+--- a/testdata/testinput12
++++ b/testdata/testinput12
+@@ -498,6 +498,16 @@
+ /(..)(*scs:(1)ab$)/match_invalid_utf
+     ab\x{df00}cde         
++# Backward scans must not enter the invalid prefix before check_subject.
++
++/(?<=a{1,2})X/utf,match_invalid_utf
++\= Expect no match
++    \x{dc00}X
++
++/\X\X/utf,match_invalid_utf
++\= Expect no match
++    \x{dc00}\x{1f1e6}\x{1f1e7}
++
+ /(?<=(.))/utf,match_invalid_utf
+     x\x{d800}
+     \x{10000}\x{dc00}
+diff --git a/testdata/testoutput10 b/testdata/testoutput10
+index 393ac207..9e124e2b 100644
+--- a/testdata/testoutput10
++++ b/testdata/testoutput10
+@@ -1779,6 +1779,18 @@ No match
+     AAA\x80BBXYZ 
+ No match
++# Backward scans must not enter the invalid prefix before check_subject.
++
++/(?<=a{1,2})X/utf,match_invalid_utf
++\= Expect no match
++    \x80X
++No match
++
++/\X\X/utf,match_invalid_utf
++\= Expect no match
++    \x80\x{1f1e6}\x{1f1e7}
++No match
++
+ /(?<=(.))/utf,match_invalid_utf
+     x\x80
+  0: 
+diff --git a/testdata/testoutput12-16 b/testdata/testoutput12-16
+index d235c11f..b0676a19 100644
+--- a/testdata/testoutput12-16
++++ b/testdata/testoutput12-16
+@@ -1659,6 +1659,18 @@ No match
+  0: ab
+  1: ab
++# Backward scans must not enter the invalid prefix before check_subject.
++
++/(?<=a{1,2})X/utf,match_invalid_utf
++\= Expect no match
++    \x{dc00}X
++No match
++
++/\X\X/utf,match_invalid_utf
++\= Expect no match
++    \x{dc00}\x{1f1e6}\x{1f1e7}
++No match
++
+ /(?<=(.))/utf,match_invalid_utf
+     x\x{d800}
+  0: 
+diff --git a/testdata/testoutput12-32 b/testdata/testoutput12-32
+index 725cb274..a97051a6 100644
+--- a/testdata/testoutput12-32
++++ b/testdata/testoutput12-32
+@@ -1658,6 +1658,18 @@ No match
+  0: ab
+  1: ab
++# Backward scans must not enter the invalid prefix before check_subject.
++
++/(?<=a{1,2})X/utf,match_invalid_utf
++\= Expect no match
++    \x{dc00}X
++No match
++
++/\X\X/utf,match_invalid_utf
++\= Expect no match
++    \x{dc00}\x{1f1e6}\x{1f1e7}
++No match
++
+ /(?<=(.))/utf,match_invalid_utf
+     x\x{d800}
+  0: 
diff --git a/patches/pcre2-10.48-Fix-repeated-substitute-escapes.patch b/patches/pcre2-10.48-Fix-repeated-substitute-escapes.patch
new file mode 100644 (file)
index 0000000..265a374
--- /dev/null
@@ -0,0 +1,75 @@
+commit c07a6e8cdc2c2c0222d2441863df534b96377f35
+Author: Nicholas Wilson <nicholas@nicholaswilson.me.uk>
+Date:   Tue Dec 2 16:21:32 2025 +0000
+
+    Fix regression in handling of repeated backslash escapes in pcre2_substitute (#857)
+
+diff --git a/src/pcre2_substitute.c b/src/pcre2_substitute.c
+index fb187258..f323c56a 100644
+--- a/src/pcre2_substitute.c
++++ b/src/pcre2_substitute.c
+@@ -115,6 +115,7 @@ for (; ptr < ptrend; ptr++)
+     int erc;
+     int errorcode;
+     uint32_t ch;
++    PCRE2_SPTR esc_end_ptr;
+     if (ptr < ptrend - 1) switch (ptr[1])
+       {
+@@ -137,6 +138,9 @@ for (; ptr < ptrend; ptr++)
+       goto EXIT;
+       }
++    esc_end_ptr = ptr;
++    ptr -= 1;  /* Rewind by one, because the for-loop will increment it */
++
+     switch(erc)
+       {
+       case 0:      /* Data character */
+@@ -160,7 +164,8 @@ for (; ptr < ptrend; ptr++)
+       default:
+       if (erc < 0)
+-          break;  /* capture group reference */
++        break;  /* capture group reference */
++      ptr = esc_end_ptr;
+       rc = PCRE2_ERROR_BADREPESCAPE;
+       goto EXIT;
+       }
+diff --git a/testdata/testinput2 b/testdata/testinput2
+index 8a905f58..e0cacced 100644
+--- a/testdata/testinput2
++++ b/testdata/testinput2
+@@ -8314,5 +8314,12 @@ a)"xI
+     foo|bar\=offset=1,substitute_subject=F|OOBAR,copy_matched_subject
+     foo|bar\=offset=1,substitute_subject=F|OOBAR,copy_matched_subject,zero_terminate
++# --------------
++# Some more tests for a substitution regression
++# --------------
++
++/foo(?<Bar>BAR)?/substitute_extended,replace=X${Bar:+\:\:text}Y
++    foo
++    fooBAR
+ # End of testinput2
+diff --git a/testdata/testoutput2 b/testdata/testoutput2
+index 08e73823..bdd431e3 100644
+--- a/testdata/testoutput2
++++ b/testdata/testoutput2
+@@ -23656,6 +23656,15 @@ Failed: error -72: substitute subject differs from prior match call
+     foo|bar\=offset=1,substitute_subject=F|OOBAR,copy_matched_subject,zero_terminate
+ Failed: error -72: substitute subject differs from prior match call
++# --------------
++# Some more tests for a substitution regression
++# --------------
++
++/foo(?<Bar>BAR)?/substitute_extended,replace=X${Bar:+\:\:text}Y
++    foo
++ 1: XY
++    fooBAR
++ 1: X::textY
+ # End of testinput2
+ Error -80: PCRE2_ERROR_BADDATA (unknown error number)
diff --git a/patches/pcre2-10.48-Fix-scan-prefix-repeat-reset.patch b/patches/pcre2-10.48-Fix-scan-prefix-repeat-reset.patch
new file mode 100644 (file)
index 0000000..470d590
--- /dev/null
@@ -0,0 +1,30 @@
+commit 7a33b226fe0dc243cbed47fcbe49025ec4aea125
+Author: Zoltan Herczeg <zherczeg7@gmail.com>
+Date:   Sun Jan 25 06:38:11 2026 +0100
+
+    Fix repeat reset for scan prefix (#875)
+
+diff --git a/src/pcre2_jit_compile.c b/src/pcre2_jit_compile.c
+index 4cca50d4..5d8c1c14 100644
+--- a/src/pcre2_jit_compile.c
++++ b/src/pcre2_jit_compile.c
+@@ -6249,6 +6249,7 @@ while (TRUE)
+       repeat = GET2(cc, 1);
+       if (repeat <= 0)
+         {
++        repeat = 1;
+         chars_end = chars;
+         continue;
+         }
+diff --git a/src/pcre2_jit_test.c b/src/pcre2_jit_test.c
+index 1fc44db5..03cc348b 100644
+--- a/src/pcre2_jit_test.c
++++ b/src/pcre2_jit_test.c
+@@ -281,6 +281,7 @@ static struct regression_test_case regression_test_cases[] = {
+       { CM, A, 0, 0, "a1277|a1377|bx487", "bX487" },
+       { 0, A, 0, 0, "(a|)b*+a", "a" },
+       { 0, A, 0, 0 | F_NOMATCH, "(.|.|.|.|.)(|.|.|.|.)(.||.|.|.)(.|.||.|.)(.|.|.||.)(.|.|.|.|)(A|.|.|.|.)(.|A|.|.|.)(.|.|A|.|.)(.|.|.|A|.)(.|.|.|.|A)(B|.|.|.|.)(.|B|.|.|.)(.|.|B|.|.)(.|.|.|B|.)(.|.|.|.|B)xa", "1234567890123456ax" },
++      { 0, A, 0, 0, "(CHAN|LINE)[ab]{0,2}", "LINE" },
+       /* Greedy and non-greedy ? operators. */
+       { MU, A, 0, 0, "(?:a)?a", "laab" },
diff --git a/patches/pcre2-10.48-Keep-escape-error-offset-in-pattern.patch b/patches/pcre2-10.48-Keep-escape-error-offset-in-pattern.patch
new file mode 100644 (file)
index 0000000..83e4ab3
--- /dev/null
@@ -0,0 +1,92 @@
+commit c49915439a1fdfb97a8b6f8ae5676c18c5ac2eea
+Author: Kartik <kartik@bugqore.com>
+Date:   Mon Aug 17 00:58:15 2026 +0530
+
+    Keep check_escape error offset within the pattern for \x{ and \o{ (#948)
+
+diff --git a/src/pcre2_compile.c b/src/pcre2_compile.c
+index c64fd273..aeda6370 100644
+--- a/src/pcre2_compile.c
++++ b/src/pcre2_compile.c
+@@ -2020,7 +2020,7 @@ else
+     else
+       {
+       *errorcodeptr = ERR64;
+-      goto ESCAPE_FAILED_FORWARD;
++      if (ptr < ptrend) goto ESCAPE_FAILED_FORWARD;
+       }
+     break;
+@@ -2107,7 +2107,7 @@ else
+         else
+           {
+           *errorcodeptr = ERR67;
+-          goto ESCAPE_FAILED_FORWARD;
++          if (ptr < ptrend) goto ESCAPE_FAILED_FORWARD;
+           }
+         }   /* End of \x{} processing */
+diff --git a/testdata/testinput2 b/testdata/testinput2
+index 4bc71fcf..a7c1c846 100644
+--- a/testdata/testinput2
++++ b/testdata/testinput2
+@@ -3987,6 +3987,10 @@
+ /^A\x{/
++/\x{2/
++
++/\o{7/
++
+ /[ab]++/B,no_auto_possess
+ /[^ab]*+/B,no_auto_possess
+diff --git a/testdata/testinput5 b/testdata/testinput5
+index d47e0c1e..098f4100 100644
+--- a/testdata/testinput5
++++ b/testdata/testinput5
+@@ -3616,4 +3616,9 @@
+     \x{e1}
+     \x{c1}
++# An unterminated \N{U+ escape at the end of the pattern must
++# report an error offset that lies within the pattern.
++
++/(*UTF)\N{U+2/
++
+ # End of testinput5
+diff --git a/testdata/testoutput2 b/testdata/testoutput2
+index ccb5667f..acb4adf7 100644
+--- a/testdata/testoutput2
++++ b/testdata/testoutput2
+@@ -13630,6 +13630,14 @@ Failed: error 167 at offset 8: non-hex character in \x{} (closing brace missing?
+ Failed: error 178 at offset 5: digits missing after \x or in \x{} or \o{} or \N{U+}
+         here: ^A\x{ |<--|
++/\x{2/
++Failed: error 167 at offset 4: non-hex character in \x{} (closing brace missing?)
++        here: \x{2 |<--|
++
++/\o{7/
++Failed: error 164 at offset 4: non-octal character in \o{} (closing brace missing?)
++        here: \o{7 |<--|
++
+ /[ab]++/B,no_auto_possess
+ ------------------------------------------------------------------
+         Bra
+diff --git a/testdata/testoutput5 b/testdata/testoutput5
+index 82b3abe9..0337d6aa 100644
+--- a/testdata/testoutput5
++++ b/testdata/testoutput5
+@@ -8335,4 +8335,11 @@ Failed: error 150 at offset 5: invalid range in character class
+     \x{c1}
+  0: \x{c1}
++# An unterminated \N{U+ escape at the end of the pattern must
++# report an error offset that lies within the pattern.
++
++/(*UTF)\N{U+2/
++Failed: error 167 at offset 12: non-hex character in \x{} (closing brace missing?)
++        here: ...UTF)\N{U+2 |<--|
++
+ # End of testinput5
diff --git a/patches/pcre2-10.48-Write-serialization-padding.patch b/patches/pcre2-10.48-Write-serialization-padding.patch
new file mode 100644 (file)
index 0000000..2546c0c
--- /dev/null
@@ -0,0 +1,80 @@
+commit edc111a6831591f68b5355a08cc9df8be8f35304
+Author: Nicholas Wilson <nicholas@nicholaswilson.me.uk>
+Date:   Sat Oct 25 10:50:27 2025 +0100
+
+    Write padding values to ensure pcre2_serialize_encode() outputs defined values (#826)
+    
+    Fixes low-severity valgrind error reported in GHSA-q7rw-r7qq-2hx6.
+
+diff --git a/src/pcre2_compile_class.c b/src/pcre2_compile_class.c
+index 9a1fc022..55b641c1 100644
+--- a/src/pcre2_compile_class.c
++++ b/src/pcre2_compile_class.c
+@@ -1802,17 +1802,14 @@ if ((xclass_props & XCLASS_REQUIRED) != 0)
+       PUT(code, 0, (uint32_t)(char_lists_size >> 1));
+       code += LINK_SIZE;
+-#if defined PCRE2_DEBUG || defined SUPPORT_VALGRIND
++      /* If we added padding to align the list, initialize the bytes to
++      defined values, so the library is valgrind-clean. It could also
++      be a security concern for clients calling into PCRE2 via bindings
++      from a memory-safe language, if pcre2_serialize_encode() exposes
++      uninitialized memory that may contain sensitive information. */
++
+       if ((char_lists_size & 0x2) != 0)
+-        {
+-        /* In debug the unused 16 bit value is set
+-        to a fixed value and marked unused. */
+-        ((uint16_t*)data)[-1] = 0x5555;
+-#ifdef SUPPORT_VALGRIND
+-        VALGRIND_MAKE_MEM_NOACCESS(data - 2, 2);
+-#endif
+-        }
+-#endif
++        ((uint16_t*)data)[-1] = 0xdead;
+       cb->char_lists_size =
+         CLIST_ALIGN_TO(char_lists_size, sizeof(uint32_t));
+diff --git a/src/pcre2test_inc.h b/src/pcre2test_inc.h
+index 8124e9ca..c4707417 100644
+--- a/src/pcre2test_inc.h
++++ b/src/pcre2test_inc.h
+@@ -2019,6 +2019,9 @@ uint32_t use_forbid_utf = forbid_utf;
+ PCRE2_SIZE patlen, full_patlen;
+ PCRE2_SIZE valgrind_access_length;
+ PCRE2_SIZE erroroffset;
++int32_t serialize_rc;
++uint8_t *serialized_bytes;
++PCRE2_SIZE serialized_size;
+ /* The perltest.sh script supports only / as a delimiter. */
+@@ -2966,6 +2969,28 @@ if ((pat_patctl.control2 & CTL2_NL_SET) != 0)
+ rc = show_pattern_info();
+ if (rc != PR_OK) return rc;
++/* Verify that the compiled structure can be serialized without generating
++memory errors. */
++
++serialize_rc = pcre2_serialize_encode((const pcre2_code **)&compiled_code, 1,
++  &serialized_bytes, &serialized_size, general_context);
++if (serialize_rc != 1)
++  {
++  cfprintf(clr_test_error, outfile, "** pcre2_serialize_encode() returned %d instead of 1\n",
++    serialize_rc);
++  return PR_ABEND;
++  }
++
++#if defined SUPPORT_VALGRIND
++if (VALGRIND_CHECK_MEM_IS_DEFINED(serialized_bytes, serialized_size) != 0)
++  {
++  cfprintf(clr_test_error, outfile, "** pcre2_serialize_encode() returned undefined data\n");
++  return PR_ABEND;
++  }
++#endif
++
++pcre2_serialize_free(serialized_bytes);
++
+ /* The "push" control requests that the compiled pattern be remembered on a
+ stack. This is mainly for testing the serialization functionality. */
index 5380525b4fd38c449af8f7352581da6e4ba612bf..789ef2cdbc437324fb1ad51f93f9273efffbe7c7 100644 (file)
@@ -250,7 +250,7 @@ surrounded by #ifndef/#endif lines so that the value can be overridden by -D. */
 #define PACKAGE_NAME "PCRE2"
 
 /* Define to the full name and version of this package. */
-#define PACKAGE_STRING "PCRE2 10.48-RC1"
+#define PACKAGE_STRING "PCRE2 10.48"
 
 /* Define to the one symbol short name of this package. */
 #define PACKAGE_TARNAME "pcre2"
@@ -259,7 +259,7 @@ surrounded by #ifndef/#endif lines so that the value can be overridden by -D. */
 #define PACKAGE_URL ""
 
 /* Define to the version of this package. */
-#define PACKAGE_VERSION "10.48-RC1"
+#define PACKAGE_VERSION "10.48"
 
 /* The value of PARENS_NEST_LIMIT specifies the maximum depth of nested
    parentheses (of any kind) in a pattern. This limits the amount of system
@@ -478,7 +478,7 @@ surrounded by #ifndef/#endif lines so that the value can be overridden by -D. */
 #endif
 
 /* Version number of package */
-#define VERSION "10.48-RC1"
+#define VERSION "10.48"
 
 /* Number of bits in a file offset, on hosts where this is settable. */
 /* #undef _FILE_OFFSET_BITS */
index 283d61a3b94646a31839431228f03896038a6a2f..f171bbdf8d592c4450fe4ec0535f70d66627900d 100644 (file)
@@ -43,8 +43,8 @@ POSSIBILITY OF SUCH DAMAGE.
 
 #define PCRE2_MAJOR           10
 #define PCRE2_MINOR           48
-#define PCRE2_PRERELEASE      -RC1
-#define PCRE2_DATE            2026-08-27
+#define PCRE2_PRERELEASE      
+#define PCRE2_DATE            2026-08-31
 
 /* When an application links to a PCRE2 DLL in Windows, the symbols that are
 imported have to be identified as such. When building PCRE2, the appropriate
index 1081cf647e39cb17bf6b37da21a06384ad20f0dd..32cb32f654f8ad3ae54415dd9401a91d8e60460a 100644 (file)
@@ -6195,7 +6195,8 @@ for (;; pptr++)
 
     if (meta < META_ASTERISK || meta > META_MINMAX_QUERY)
       {
-      if (OFLOW_MAX - *lengthptr < (PCRE2_SIZE)(code - orig_code))
+      if (*lengthptr > OFLOW_MAX ||
+          OFLOW_MAX - *lengthptr < (PCRE2_SIZE)(code - orig_code))
         {
         *errorcodeptr = ERR20;   /* Integer overflow */
         cb->erroroffset = 0;
@@ -8802,7 +8803,8 @@ for (;;)
     *reqcuflagsptr = reqcuflags;
     if (lengthptr != NULL)
       {
-      if (OFLOW_MAX - *lengthptr < length)
+      if (*lengthptr > MAX_PATTERN_SIZE ||
+          MAX_PATTERN_SIZE - *lengthptr < length)
         {
         *errorcodeptr = ERR20;
         return 0;
@@ -8825,6 +8827,19 @@ for (;;)
     {
     code = *codeptr + 1 + LINK_SIZE + skipunits;
     length += 1 + LINK_SIZE;
+
+    /* Move the accumulated length into *lengthptr, providing the next call to
+    compile_branch with as much space in &length and &code as the first did. */
+
+    if (*lengthptr > MAX_PATTERN_SIZE ||
+        MAX_PATTERN_SIZE - *lengthptr < length)
+      {
+      *errorcodeptr = ERR20;
+      cb->erroroffset = 0;
+      return 0;
+      }
+    *lengthptr += length;
+    length = 0;
     }
   else
     {
@@ -10851,7 +10866,8 @@ if (errorcode != 0) goto HAD_CB_ERROR;  /* Offset is in cb.erroroffset */
 #if defined SUPPORT_WIDE_CHARS
 PCRE2_ASSERT((cb.char_lists_size & 0x3) == 0);
 if (length > MAX_PATTERN_SIZE ||
-    MAX_PATTERN_SIZE - length < (cb.char_lists_size / sizeof(PCRE2_UCHAR)))
+    BYTES2CU(cb.char_lists_size) > MAX_PATTERN_SIZE ||
+    MAX_PATTERN_SIZE - length < BYTES2CU(cb.char_lists_size))
 #else
 if (length > MAX_PATTERN_SIZE)
 #endif
@@ -10876,11 +10892,36 @@ if (cb.char_lists_size != 0)
   /* Align to 32 bit first. This ensures the
   allocated area will also be 32 bit aligned. */
   re_blocksize = (PCRE2_SIZE)CLIST_ALIGN_TO(re_blocksize, sizeof(uint32_t));
+#else
+  /* Already 32 bit aligned. */
 #endif
+
+  /* We have bounded the length and BYTES2CU(char_lists_size) to
+  MAX_PATTERN_SIZE units, however (with 32-bit code units) char_lists_size
+  in bytes could still be extremely close to (or greater than) SIZE_MAX, so
+  we require another overflow check. */
+
+  if (cb.char_lists_size > PCRE2_SIZE_MAX - re_blocksize)
+    {
+    errorcode = ERR20;
+    cb.erroroffset = 0;
+    goto HAD_CB_ERROR;
+    }
+
   re_blocksize += cb.char_lists_size;
   }
 #endif
 
+if (length > BYTES2CU(PCRE2_SIZE_MAX - re_blocksize))
+  {
+  /* Given the current value of 2^30 for MAX_PATTERN_SIZE, this block is only
+  reachable when both PCRE2_CODE_UNIT_WIDTH >= 16 and sizeof(size_t) is
+  32 bits. */
+  errorcode = ERR20;
+  cb.erroroffset = 0;
+  goto HAD_CB_ERROR;
+  }
+
 re_blocksize += CU2BYTES(length);
 
 if (re_blocksize > ccontext->max_pattern_compiled_length)
@@ -10890,7 +10931,15 @@ if (re_blocksize > ccontext->max_pattern_compiled_length)
   goto HAD_CB_ERROR;
   }
 
+if (sizeof(pcre2_real_code) > PCRE2_SIZE_MAX - re_blocksize)
+  {
+  errorcode = ERR20;
+  cb.erroroffset = 0;
+  goto HAD_CB_ERROR;
+  }
+
 re_blocksize += sizeof(pcre2_real_code);
+
 re = (pcre2_real_code *)
   ccontext->memctl.malloc(re_blocksize, ccontext->memctl.memory_data);
 if (re == NULL)
index c6f30d6fcf56b33efbbab2e493ffe26ce9b07385..c06066436cce914722a6a857da82d5d739562259 100644 (file)
@@ -498,7 +498,7 @@ static const uint32_t char_list_starts[] = {
 
 static class_ranges *
 compile_optimize_class(uint32_t *start_ptr, uint32_t options,
-  uint32_t xoptions, compile_block *cb)
+  uint32_t xoptions, int *errorcodeptr, compile_block *cb)
 {
 class_ranges* cranges;
 uint32_t *ptr;
@@ -538,12 +538,23 @@ PCRE2_ASSERT((range_list_size & 0x1) == 0);
 
 total_size = range_list_size +
    ((range_list_size >= 2) ? CHAR_LIST_EXTRA_SIZE : 0);
+if (total_size > (PCRE2_SIZE_MAX - sizeof(class_ranges)) / sizeof(uint32_t))
+  {
+  *errorcodeptr = ERR20;
+  cb->erroroffset = 0;
+  return NULL;
+  }
 
 cranges = cb->cx->memctl.malloc(
   sizeof(class_ranges) + total_size * sizeof(uint32_t),
   cb->cx->memctl.memory_data);
 
-if (cranges == NULL) return NULL;
+if (cranges == NULL)
+  {
+  *errorcodeptr = ERR21;
+  cb->erroroffset = 0;
+  return NULL;
+  }
 
 cranges->header.next = NULL;
 #ifdef PCRE2_DEBUG
@@ -1120,13 +1131,10 @@ if (utf)
   {
   if (lengthptr != NULL)
     {
-    cranges = compile_optimize_class(pptr, options, xoptions, cb);
+    cranges = compile_optimize_class(pptr, options, xoptions, errorcodeptr, cb);
 
     if (cranges == NULL)
-      {
-      *errorcodeptr = ERR21;
       return NULL;
-      }
 
     /* Caching the pre-processed character ranges. */
     if (cb->last_data != NULL)
@@ -1759,18 +1767,17 @@ if ((xclass_props & XCLASS_REQUIRED) != 0)
       *lengthptr += 1 + LINK_SIZE;
 #endif
 
-      cb->char_lists_size += char_lists_size;
-
-      char_lists_size /= sizeof(PCRE2_UCHAR);
+      PCRE2_ASSERT(BYTES2CU(cb->char_lists_size) <= MAX_PATTERN_SIZE);
 
-      /* Storage space for character lists is included
-      in the maximum pattern size. */
-      if (*lengthptr > MAX_PATTERN_SIZE ||
-          MAX_PATTERN_SIZE - *lengthptr < char_lists_size)
+      if (char_lists_size > PCRE2_SIZE_MAX - cb->char_lists_size ||
+          BYTES2CU(char_lists_size) > MAX_PATTERN_SIZE ||
+          BYTES2CU(cb->char_lists_size) > MAX_PATTERN_SIZE - BYTES2CU(char_lists_size))
         {
         *errorcodeptr = ERR20;   /* Pattern is too large */
         return NULL;
         }
+
+      cb->char_lists_size += char_lists_size;
       }
     else
       {
@@ -1793,6 +1800,8 @@ if ((xclass_props & XCLASS_REQUIRED) != 0)
       Each list is aligned to 32 bit with an optional unused
       16 bit value at the beginning of the character list. */
 
+      PCRE2_ASSERT(char_lists_size <= PCRE2_SIZE_MAX - cb->char_lists_size);
+
       cb->char_lists_size += char_lists_size;
       data = (uint8_t*)cb->start_code - cb->char_lists_size;
 
index 314e97754e25f9629091d4aaaf4bc7625b32e5e3..8e9512c4e0f4c20ee08740185ab4007a5e36e1f5 100644 (file)
@@ -405,8 +405,8 @@ return (mb->callout)(cb, mb->callout_data);
 
 /* This function is called when internal_dfa_match() is about to be called
 recursively and there is insufficient working space left in the current
-workspace block. If there's an existing next block, use it; otherwise get a new
-block unless the heap limit is reached.
+workspace block. If there's a sufficiently large next block, use it; get a new
+block unless the heap limit is (or has been) reached.
 
 Arguments:
   rwsptr     pointer to block pointer (updated)
@@ -422,9 +422,18 @@ more_workspace(RWS_anchor **rwsptr, unsigned int ovecsize, dfa_match_block *mb)
 {
 RWS_anchor *rws = *rwsptr;
 RWS_anchor *new;
+uint32_t requested;
+
+PCRE2_ASSERT(ovecsize <= UINT32_MAX - RWS_RSIZE - RWS_ANCHOR_SIZE);
+requested = RWS_RSIZE + ovecsize + RWS_ANCHOR_SIZE;
 
 if (rws->next != NULL)
   {
+  /* Although the initial block is large, and subsequent ones try to double, the
+  heap limit may cause the last one to be smaller; in this case, we have already
+  hit the heap limit and allocating a larger block will not be possible. */
+  if (rws->next->size < requested)
+    return PCRE2_ERROR_HEAPLIMIT;
   new = rws->next;
   }
 
@@ -434,14 +443,30 @@ overflow. */
 
 else
   {
-  uint32_t newsize = (rws->size >= UINT32_MAX/(sizeof(int)*2))? UINT32_MAX/sizeof(int) : rws->size * 2;
+  uint32_t newsize = (rws->size >= (UINT32_MAX/sizeof(int))/2)?
+    UINT32_MAX/sizeof(int) : rws->size * 2;
   uint32_t newsizeK = newsize/(1024/sizeof(int));
 
-  if (newsizeK + mb->heap_used > mb->heap_limit)
-    newsizeK = (uint32_t)(mb->heap_limit - mb->heap_used);
-  newsize = newsizeK*(1024/sizeof(int));
+  /* Clamp the allocation to the remaining heap allowance with care for overflows */
+
+  if (mb->heap_used >= mb->heap_limit)
+    {
+    newsize = 0;
+    newsizeK = 0;
+    }
+  else
+    {
+    PCRE2_SIZE availableK = mb->heap_limit - mb->heap_used;
+    /* newsize always capped at UINT32_MAX/sizeof(int), so newsizeK also capped;
+    and - if availableK is smaller - then multiplication to form newsize is safe */
+    if (newsizeK > availableK)
+      {
+      newsize = (uint32_t)(availableK*(1024/sizeof(int)));
+      newsizeK = availableK;
+      }
+    }
 
-  if (newsize < RWS_RSIZE + ovecsize + RWS_ANCHOR_SIZE)
+  if (newsize < requested)
     return PCRE2_ERROR_HEAPLIMIT;
   new = mb->memctl.malloc(newsize*sizeof(int), mb->memctl.memory_data);
   if (new == NULL) return PCRE2_ERROR_NOMEMORY;
@@ -2801,6 +2826,7 @@ for (;;)
 
         local_offsets = (PCRE2_SIZE *)(RWS + rws->size - rws->free);
         local_workspace = ((int *)local_offsets) + RWS_OVEC_OSIZE;
+        PCRE2_ASSERT(rws->free >= RWS_RSIZE + RWS_OVEC_OSIZE);
         rws->free -= RWS_RSIZE + RWS_OVEC_OSIZE;
 
         while (*endasscode == OP_ALT) endasscode += GET(endasscode, 1);
@@ -2900,6 +2926,7 @@ for (;;)
 
           local_offsets = (PCRE2_SIZE *)(RWS + rws->size - rws->free);
           local_workspace = ((int *)local_offsets) + RWS_OVEC_OSIZE;
+          PCRE2_ASSERT(rws->free >= RWS_RSIZE + RWS_OVEC_OSIZE);
           rws->free -= RWS_RSIZE + RWS_OVEC_OSIZE;
 
           while (*endasscode == OP_ALT) endasscode += GET(endasscode, 1);
@@ -2951,6 +2978,7 @@ for (;;)
 
         local_offsets = (PCRE2_SIZE *)(RWS + rws->size - rws->free);
         local_workspace = ((int *)local_offsets) + RWS_OVEC_RSIZE;
+        PCRE2_ASSERT(rws->free >= RWS_RSIZE + RWS_OVEC_RSIZE);
         rws->free -= RWS_RSIZE + RWS_OVEC_RSIZE;
 
         /* Check for repeating a recursion without advancing the subject
@@ -3050,6 +3078,7 @@ for (;;)
 
         local_offsets = (PCRE2_SIZE *)(RWS + rws->size - rws->free);
         local_workspace = ((int *)local_offsets) + RWS_OVEC_OSIZE;
+        PCRE2_ASSERT(rws->free >= RWS_RSIZE + RWS_OVEC_OSIZE);
         rws->free -= RWS_RSIZE + RWS_OVEC_OSIZE;
 
         if (codevalue == OP_BRAPOSZERO)
@@ -3149,6 +3178,7 @@ for (;;)
 
         local_offsets = (PCRE2_SIZE *)(RWS + rws->size - rws->free);
         local_workspace = ((int *)local_offsets) + RWS_OVEC_OSIZE;
+        PCRE2_ASSERT(rws->free >= RWS_RSIZE + RWS_OVEC_OSIZE);
         rws->free -= RWS_RSIZE + RWS_OVEC_OSIZE;
 
         rc = internal_dfa_match(
index 1b7f04b4b2f38e8896938fa09b18c7147833ae98..fea098a7631d668842303b7fd57d9810f1855505 100644 (file)
@@ -54,12 +54,12 @@ support, because some compilers do not like functionless source files. */
 
 #ifndef SUPPORT_UNICODE
 PCRE2_SPTR
-PRIV(extuni)(uint32_t c, PCRE2_SPTR eptr, PCRE2_SPTR start_subject,
+PRIV(extuni)(uint32_t c, PCRE2_SPTR eptr, PCRE2_SPTR check_subject,
   PCRE2_SPTR end_subject, BOOL utf, int *xcount)
 {
 (void)c;
 (void)eptr;
-(void)start_subject;
+(void)check_subject;
 (void)end_subject;
 (void)utf;
 (void)xcount;
@@ -80,7 +80,7 @@ same behaviour.
 Arguments:
   c              the first character
   eptr           pointer to next character
-  start_subject  pointer to start of subject
+  check_subject  pointer to start of validated subject
   end_subject    pointer to end of subject
   utf            TRUE if in UTF mode
   xcount         pointer to count of additional characters,
@@ -90,7 +90,7 @@ Returns:         pointer after the end of the sequence
 */
 
 PCRE2_SPTR
-PRIV(extuni)(uint32_t c, PCRE2_SPTR eptr, PCRE2_SPTR start_subject,
+PRIV(extuni)(uint32_t c, PCRE2_SPTR eptr, PCRE2_SPTR check_subject,
   PCRE2_SPTR end_subject, BOOL utf, int *xcount)
 {
 BOOL was_ep_ZWJ = FALSE;
@@ -121,7 +121,7 @@ while (eptr < end_subject)
 
     /* bptr is pointing to the left-hand character */
 
-    while (bptr > start_subject)
+    while (bptr > check_subject)
       {
       bptr--;
       if (utf)
index a5a8421f7c219dc66b7fbb87afffe148664bda40..966576e191b056b1beba81caad5eeceea84054b8 100644 (file)
@@ -2895,7 +2895,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode,
     else
       {
       GETCHARINCTEST(fc, Feptr);
-      Feptr = PRIV(extuni)(fc, Feptr, mb->start_subject, mb->end_subject, utf,
+      Feptr = PRIV(extuni)(fc, Feptr, mb->check_subject, mb->end_subject, utf,
         NULL);
       }
     CHECK_PARTIAL();
@@ -3246,7 +3246,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode,
           else
             {
             GETCHARINCTEST(fc, Feptr);
-            Feptr = PRIV(extuni)(fc, Feptr, mb->start_subject,
+            Feptr = PRIV(extuni)(fc, Feptr, mb->check_subject,
               mb->end_subject, utf, NULL);
             }
           CHECK_PARTIAL();
@@ -4071,7 +4071,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode,
           else
             {
             GETCHARINCTEST(fc, Feptr);
-            Feptr = PRIV(extuni)(fc, Feptr, mb->start_subject, mb->end_subject,
+            Feptr = PRIV(extuni)(fc, Feptr, mb->check_subject, mb->end_subject,
               utf, NULL);
             }
           CHECK_PARTIAL();
@@ -4660,7 +4660,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode,
           else
             {
             GETCHARINCTEST(fc, Feptr);
-            Feptr = PRIV(extuni)(fc, Feptr, mb->start_subject, mb->end_subject,
+            Feptr = PRIV(extuni)(fc, Feptr, mb->check_subject, mb->end_subject,
               utf, NULL);
             }
           CHECK_PARTIAL();
@@ -6243,7 +6243,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode,
       {
       for (i = 0; i < Lmax; i++)
         {
-        if (Feptr == mb->start_subject)
+        if (Feptr <= mb->check_subject)
           {
           if (i < Lmin) RRETURN(MATCH_NOMATCH);
           Lmax = i;
index d9e6ba8cbf3fda22238ed85e0f691e73408cc976..bfa9dad8d30de73c41c58fcc3deb64d61d0f248f 100644 (file)
     AAA\x80BXYZ 
     AAA\x80BBXYZ 
 
+# Backward scans must not enter the invalid prefix before check_subject.
+
+/(?<=a{1,2})X/utf,match_invalid_utf
+\= Expect no match
+    \x80X
+
+/\X\X/utf,match_invalid_utf
+\= Expect no match
+    \x80\x{1f1e6}\x{1f1e7}
+
 /(?<=(.))/utf,match_invalid_utf
     x\x80
     \x{10000}\x80
index 01cc76a491b851dbe66959390da9cc6c2c458fc9..c4a89a263c93ec70e20ee67b76a4c53b82de29ba 100644 (file)
 /(..)(*scs:(1)ab$)/match_invalid_utf
     ab\x{df00}cde         
 
+# Backward scans must not enter the invalid prefix before check_subject.
+
+/(?<=a{1,2})X/utf,match_invalid_utf
+\= Expect no match
+    \x{dc00}X
+
+/\X\X/utf,match_invalid_utf
+\= Expect no match
+    \x{dc00}\x{1f1e6}\x{1f1e7}
+
 /(?<=(.))/utf,match_invalid_utf
     x\x{d800}
     \x{10000}\x{dc00}
index f6f5cbf4b79937354912270394d2e7d51175cbbd..197f6f761015543af6fbae2c3db19e612328bb98 100644 (file)
     abc\=replace=xyz
     abc\=replace=xyz,substitute_matched
 
+# --------------
+
+# Test workspace resizing and workspace re-use
+
+/(*LIMIT_HEAP=4)(?=(?=(?=(?=(?=(?=(?=(?=a))(?R)))))))./
+    a\=dfa
+
 # End of testinput6
index 393ac2076ce3bb82993f42ff822759224c7c84f4..9e124e2b2705a5d049a859c7434255e31284c143 100644 (file)
@@ -1779,6 +1779,18 @@ No match
     AAA\x80BBXYZ 
 No match
 
+# Backward scans must not enter the invalid prefix before check_subject.
+
+/(?<=a{1,2})X/utf,match_invalid_utf
+\= Expect no match
+    \x80X
+No match
+
+/\X\X/utf,match_invalid_utf
+\= Expect no match
+    \x80\x{1f1e6}\x{1f1e7}
+No match
+
 /(?<=(.))/utf,match_invalid_utf
     x\x80
  0: 
index d235c11f2a1f4447a2a792dcbd2a93e69daad79c..b0676a19a2eddccd90f666d38e20c7260eefa67b 100644 (file)
@@ -1659,6 +1659,18 @@ No match
  0: ab
  1: ab
 
+# Backward scans must not enter the invalid prefix before check_subject.
+
+/(?<=a{1,2})X/utf,match_invalid_utf
+\= Expect no match
+    \x{dc00}X
+No match
+
+/\X\X/utf,match_invalid_utf
+\= Expect no match
+    \x{dc00}\x{1f1e6}\x{1f1e7}
+No match
+
 /(?<=(.))/utf,match_invalid_utf
     x\x{d800}
  0: 
index 725cb274ea7eefa38458f742377ca77a3bf2c1fe..a97051a6835cce693356d1572a936b35f0c30e76 100644 (file)
@@ -1658,6 +1658,18 @@ No match
  0: ab
  1: ab
 
+# Backward scans must not enter the invalid prefix before check_subject.
+
+/(?<=a{1,2})X/utf,match_invalid_utf
+\= Expect no match
+    \x{dc00}X
+No match
+
+/\X\X/utf,match_invalid_utf
+\= Expect no match
+    \x{dc00}\x{1f1e6}\x{1f1e7}
+No match
+
 /(?<=(.))/utf,match_invalid_utf
     x\x{d800}
  0: 
index 8ecf0040c4e8685955f50d425bd6383dc891ba87..4316c8a6da6c4a2f18f645602fff8dc6ed2a80b3 100644 (file)
@@ -8237,4 +8237,12 @@ Failed: error -42: pattern contains an item that is not supported for DFA matchi
     abc\=replace=xyz,substitute_matched
 Failed: error -41: function is not supported for DFA matching
 
+# --------------
+
+# Test workspace resizing and workspace re-use
+
+/(*LIMIT_HEAP=4)(?=(?=(?=(?=(?=(?=(?=(?=a))(?R)))))))./
+    a\=dfa
+Failed: error -63: heap limit exceeded
+
 # End of testinput6